diff --git a/e2e/react-router/basic-file-based-code-splitting/src/routeTree.gen.ts b/e2e/react-router/basic-file-based-code-splitting/src/routeTree.gen.ts
index 442312342a..dfc5027f49 100644
--- a/e2e/react-router/basic-file-based-code-splitting/src/routeTree.gen.ts
+++ b/e2e/react-router/basic-file-based-code-splitting/src/routeTree.gen.ts
@@ -13,6 +13,7 @@ import type { CreateFileRoute, FileRoutesByPath } from '@tanstack/react-router'
 import { Route as rootRouteImport } from './routes/__root'
 import { Route as WithoutLoaderRouteImport } from './routes/without-loader'
 import { Route as ViewportTestRouteImport } from './routes/viewport-test'
+import { Route as SharedSingletonRouteImport } from './routes/shared-singleton'
 import { Route as PostsRouteImport } from './routes/posts'
 import { Route as LayoutRouteImport } from './routes/_layout'
 import { Route as IndexRouteImport } from './routes/index'
@@ -32,6 +33,11 @@ const ViewportTestRoute = ViewportTestRouteImport.update({
   path: '/viewport-test',
   getParentRoute: () => rootRouteImport,
 } as any)
+const SharedSingletonRoute = SharedSingletonRouteImport.update({
+  id: '/shared-singleton',
+  path: '/shared-singleton',
+  getParentRoute: () => rootRouteImport,
+} as any)
 const PostsRoute = PostsRouteImport.update({
   id: '/posts',
   path: '/posts',
@@ -74,6 +80,7 @@ const LayoutLayout2LayoutARoute = LayoutLayout2LayoutARouteImport.update({
 export interface FileRoutesByFullPath {
   '/': typeof IndexRoute
   '/posts': typeof PostsRouteWithChildren
+  '/shared-singleton': typeof SharedSingletonRoute
   '/viewport-test': typeof ViewportTestRoute
   '/without-loader': typeof WithoutLoaderRoute
   '/posts/$postId': typeof PostsPostIdRoute
@@ -83,6 +90,7 @@ export interface FileRoutesByFullPath {
 }
 export interface FileRoutesByTo {
   '/': typeof IndexRoute
+  '/shared-singleton': typeof SharedSingletonRoute
   '/viewport-test': typeof ViewportTestRoute
   '/without-loader': typeof WithoutLoaderRoute
   '/posts/$postId': typeof PostsPostIdRoute
@@ -95,6 +103,7 @@ export interface FileRoutesById {
   '/': typeof IndexRoute
   '/_layout': typeof LayoutRouteWithChildren
   '/posts': typeof PostsRouteWithChildren
+  '/shared-singleton': typeof SharedSingletonRoute
   '/viewport-test': typeof ViewportTestRoute
   '/without-loader': typeof WithoutLoaderRoute
   '/_layout/_layout-2': typeof LayoutLayout2RouteWithChildren
@@ -108,6 +117,7 @@ export interface FileRouteTypes {
   fullPaths:
     | '/'
     | '/posts'
+    | '/shared-singleton'
     | '/viewport-test'
     | '/without-loader'
     | '/posts/$postId'
@@ -117,6 +127,7 @@ export interface FileRouteTypes {
   fileRoutesByTo: FileRoutesByTo
   to:
     | '/'
+    | '/shared-singleton'
     | '/viewport-test'
     | '/without-loader'
     | '/posts/$postId'
@@ -128,6 +139,7 @@ export interface FileRouteTypes {
     | '/'
     | '/_layout'
     | '/posts'
+    | '/shared-singleton'
     | '/viewport-test'
     | '/without-loader'
     | '/_layout/_layout-2'
@@ -141,6 +153,7 @@ export interface RootRouteChildren {
   IndexRoute: typeof IndexRoute
   LayoutRoute: typeof LayoutRouteWithChildren
   PostsRoute: typeof PostsRouteWithChildren
+  SharedSingletonRoute: typeof SharedSingletonRoute
   ViewportTestRoute: typeof ViewportTestRoute
   WithoutLoaderRoute: typeof WithoutLoaderRoute
 }
@@ -161,6 +174,13 @@ declare module '@tanstack/react-router' {
       preLoaderRoute: typeof ViewportTestRouteImport
       parentRoute: typeof rootRouteImport
     }
+    '/shared-singleton': {
+      id: '/shared-singleton'
+      path: '/shared-singleton'
+      fullPath: '/shared-singleton'
+      preLoaderRoute: typeof SharedSingletonRouteImport
+      parentRoute: typeof rootRouteImport
+    }
     '/posts': {
       id: '/posts'
       path: '/posts'
@@ -171,7 +191,7 @@ declare module '@tanstack/react-router' {
     '/_layout': {
       id: '/_layout'
       path: ''
-      fullPath: ''
+      fullPath: '/'
       preLoaderRoute: typeof LayoutRouteImport
       parentRoute: typeof rootRouteImport
     }
@@ -199,7 +219,7 @@ declare module '@tanstack/react-router' {
     '/_layout/_layout-2': {
       id: '/_layout/_layout-2'
       path: ''
-      fullPath: ''
+      fullPath: '/'
       preLoaderRoute: typeof LayoutLayout2RouteImport
       parentRoute: typeof LayoutRoute
     }
@@ -247,6 +267,15 @@ declare module './routes/posts' {
     FileRoutesByPath['/posts']['fullPath']
   >
 }
+declare module './routes/shared-singleton' {
+  const createFileRoute: CreateFileRoute<
+    '/shared-singleton',
+    FileRoutesByPath['/shared-singleton']['parentRoute'],
+    FileRoutesByPath['/shared-singleton']['id'],
+    FileRoutesByPath['/shared-singleton']['path'],
+    FileRoutesByPath['/shared-singleton']['fullPath']
+  >
+}
 declare module './routes/viewport-test' {
   const createFileRoute: CreateFileRoute<
     '/viewport-test',
@@ -352,6 +381,7 @@ const rootRouteChildren: RootRouteChildren = {
   IndexRoute: IndexRoute,
   LayoutRoute: LayoutRouteWithChildren,
   PostsRoute: PostsRouteWithChildren,
+  SharedSingletonRoute: SharedSingletonRoute,
   ViewportTestRoute: ViewportTestRoute,
   WithoutLoaderRoute: WithoutLoaderRoute,
 }
diff --git a/e2e/react-router/basic-file-based-code-splitting/src/routes/__root.tsx b/e2e/react-router/basic-file-based-code-splitting/src/routes/__root.tsx
index 8820f73e53..cb2a94ee19 100644
--- a/e2e/react-router/basic-file-based-code-splitting/src/routes/__root.tsx
+++ b/e2e/react-router/basic-file-based-code-splitting/src/routes/__root.tsx
@@ -51,6 +51,15 @@ function RootComponent() {
         >
           without-loader
         </Link>{' '}
+        <Link
+          to="/shared-singleton"
+          activeProps={{
+            className: 'font-bold',
+          }}
+          data-testid="shared-singleton-link"
+        >
+          shared-singleton
+        </Link>{' '}
         <Link
           // @ts-expect-error
           to="/this-route-does-not-exist"
diff --git a/e2e/react-router/basic-file-based-code-splitting/src/routes/shared-singleton.tsx b/e2e/react-router/basic-file-based-code-splitting/src/routes/shared-singleton.tsx
new file mode 100644
index 0000000000..b0a20b5991
--- /dev/null
+++ b/e2e/react-router/basic-file-based-code-splitting/src/routes/shared-singleton.tsx
@@ -0,0 +1,54 @@
+import * as React from 'react'
+
+// All shared state lives in declarations — no bare expression statements.
+// The singleton tracks how many times this module scope executes.
+const singleton = (() => {
+  const g = globalThis as any
+  g.__tsrSharedSingleton ??= { initCount: 0 }
+  g.__tsrSharedSingleton.initCount++
+  return { initCountAtCreate: g.__tsrSharedSingleton.initCount as number }
+})()
+
+function getInitCount() {
+  return (globalThis as any).__tsrSharedSingleton?.initCount as number
+}
+
+export const Route = createFileRoute({
+  loader: () => {
+    return {
+      loaderSawInitCount: getInitCount(),
+      initCountAtCreateFromLoader: singleton.initCountAtCreate,
+    }
+  },
+  component: SharedSingletonComponent,
+})
+
+function SharedSingletonComponent() {
+  const data = Route.useLoaderData()
+
+  return (
+    <div className="p-2 space-y-2">
+      <h3 className="text-lg font-bold">Shared Singleton</h3>
+      <div>
+        initCount (global):{' '}
+        <span data-testid="shared-init-count">{getInitCount()}</span>
+      </div>
+      <div>
+        loaderSawInitCount:{' '}
+        <span data-testid="shared-loader-saw">{data.loaderSawInitCount}</span>
+      </div>
+      <div>
+        initCountAtCreate (loader module):{' '}
+        <span data-testid="shared-created-at-loader">
+          {data.initCountAtCreateFromLoader}
+        </span>
+      </div>
+      <div>
+        initCountAtCreate (component module):{' '}
+        <span data-testid="shared-created-at-module">
+          {singleton.initCountAtCreate}
+        </span>
+      </div>
+    </div>
+  )
+}
diff --git a/e2e/react-router/basic-file-based-code-splitting/tests/shared-bindings.spec.ts b/e2e/react-router/basic-file-based-code-splitting/tests/shared-bindings.spec.ts
new file mode 100644
index 0000000000..512943c10d
--- /dev/null
+++ b/e2e/react-router/basic-file-based-code-splitting/tests/shared-bindings.spec.ts
@@ -0,0 +1,17 @@
+import { expect, test } from '@playwright/test'
+
+test.beforeEach(async ({ page }) => {
+  await page.goto('/')
+})
+
+test('shared module bindings should init once', async ({ page }) => {
+  await page.getByTestId('shared-singleton-link').click()
+
+  // If module scope is duplicated between reference + split chunk, this becomes "2".
+  await expect(page.getByTestId('shared-init-count')).toHaveText('1')
+
+  // Extra signals (useful when debugging failures)
+  await expect(page.getByTestId('shared-loader-saw')).toHaveText('1')
+  await expect(page.getByTestId('shared-created-at-loader')).toHaveText('1')
+  await expect(page.getByTestId('shared-created-at-module')).toHaveText('1')
+})
diff --git a/packages/router-plugin/src/core/code-splitter/compilers.ts b/packages/router-plugin/src/core/code-splitter/compilers.ts
index c8c57be691..766a6e7790 100644
--- a/packages/router-plugin/src/core/code-splitter/compilers.ts
+++ b/packages/router-plugin/src/core/code-splitter/compilers.ts
@@ -7,7 +7,7 @@ import {
   generateFromAst,
   parseAst,
 } from '@tanstack/router-utils'
-import { tsrSplit } from '../constants'
+import { tsrShared, tsrSplit } from '../constants'
 import { routeHmrStatement } from '../route-hmr-statement'
 import { createIdentifier } from './path-ids'
 import { getFrameworkOptions } from './framework-options'
@@ -94,6 +94,11 @@ function removeSplitSearchParamFromFilename(filename: string) {
   return bareFilename!
 }
 
+export function addSharedSearchParamToFilename(filename: string) {
+  const [bareFilename] = filename.split('?')
+  return `${bareFilename}?${tsrShared}=1`
+}
+
 const splittableCreateRouteFns = ['createFileRoute']
 const unsplittableCreateRouteFns = [
   'createRootRoute',
@@ -104,6 +109,530 @@ const allCreateRouteFns = [
   ...unsplittableCreateRouteFns,
 ]
 
+/**
+ * Recursively walk an AST node and collect referenced identifier-like names.
+ * Much cheaper than babel.traverse — no path/scope overhead.
+ *
+ * Notes:
+ * - Uses @babel/types `isReferenced` to avoid collecting non-references like
+ *   object keys, member expression properties, or binding identifiers.
+ * - Also handles JSX identifiers for component references.
+ */
+export function collectIdentifiersFromNode(node: t.Node): Set<string> {
+  const ids = new Set<string>()
+
+  ;(function walk(
+    n: t.Node | null | undefined,
+    parent?: t.Node,
+    grandparent?: t.Node,
+    parentKey?: string,
+  ) {
+    if (!n) return
+
+    if (t.isIdentifier(n)) {
+      // When we don't have parent info (node passed in isolation), treat as referenced.
+      if (!parent || t.isReferenced(n, parent, grandparent)) {
+        ids.add(n.name)
+      }
+      return
+    }
+
+    if (t.isJSXIdentifier(n)) {
+      // Skip attribute names: <div data-testid="x" />
+      if (parent && t.isJSXAttribute(parent) && parentKey === 'name') {
+        return
+      }
+
+      // Skip member properties: <Foo.Bar /> should count Foo, not Bar
+      if (
+        parent &&
+        t.isJSXMemberExpression(parent) &&
+        parentKey === 'property'
+      ) {
+        return
+      }
+
+      // Intrinsic elements (lowercase) are not identifiers
+      const first = n.name[0]
+      if (first && first === first.toLowerCase()) {
+        return
+      }
+
+      ids.add(n.name)
+      return
+    }
+
+    for (const key of t.VISITOR_KEYS[n.type] || []) {
+      const child = (n as any)[key]
+      if (Array.isArray(child)) {
+        for (const c of child) {
+          if (c && typeof c.type === 'string') {
+            walk(c, n, parent, key)
+          }
+        }
+      } else if (child && typeof child.type === 'string') {
+        walk(child, n, parent, key)
+      }
+    }
+  })(node)
+
+  return ids
+}
+
+/**
+ * Build a map from binding name → declaration AST node for all
+ * locally-declared module-level bindings. Built once, O(1) lookup.
+ */
+export function buildDeclarationMap(ast: t.File): Map<string, t.Node> {
+  const map = new Map<string, t.Node>()
+  for (const stmt of ast.program.body) {
+    const decl =
+      t.isExportNamedDeclaration(stmt) && stmt.declaration
+        ? stmt.declaration
+        : stmt
+
+    if (t.isVariableDeclaration(decl)) {
+      for (const declarator of decl.declarations) {
+        for (const name of collectIdentifiersFromPattern(declarator.id)) {
+          map.set(name, declarator)
+        }
+      }
+    } else if (t.isFunctionDeclaration(decl) && decl.id) {
+      map.set(decl.id.name, decl)
+    } else if (t.isClassDeclaration(decl) && decl.id) {
+      map.set(decl.id.name, decl)
+    }
+  }
+  return map
+}
+
+/**
+ * Build a dependency graph: for each local binding, the set of other local
+ * bindings its declaration references. Built once via simple node walking.
+ */
+export function buildDependencyGraph(
+  declMap: Map<string, t.Node>,
+  localBindings: Set<string>,
+): Map<string, Set<string>> {
+  const graph = new Map<string, Set<string>>()
+  for (const [name, declNode] of declMap) {
+    if (!localBindings.has(name)) continue
+    const allIds = collectIdentifiersFromNode(declNode)
+    const deps = new Set<string>()
+    for (const id of allIds) {
+      if (id !== name && localBindings.has(id)) deps.add(id)
+    }
+    graph.set(name, deps)
+  }
+  return graph
+}
+
+/**
+ * Computes module-level bindings that are shared between split and non-split
+ * route properties. These bindings need to be extracted into a shared virtual
+ * module to avoid double-initialization.
+ *
+ * A binding is "shared" if it is referenced by at least one split property
+ * AND at least one non-split property. Only locally-declared module-level
+ * bindings are candidates (not imports — bundlers dedupe those).
+ */
+export function computeSharedBindings(opts: {
+  code: string
+  codeSplitGroupings: CodeSplitGroupings
+}): Set<string> {
+  const ast = parseAst(opts)
+
+  // Early bailout: collect all module-level locally-declared binding names.
+  // This is a cheap loop over program.body (no traversal). If the file has
+  // no local bindings (aside from `Route`), nothing can be shared — skip
+  // the expensive babel.traverse entirely.
+  const localModuleLevelBindings = new Set<string>()
+  for (const node of ast.program.body) {
+    collectLocalBindingsFromStatement(node, localModuleLevelBindings)
+  }
+
+  // File-based routes always export a route config binding (usually `Route`).
+  // This must never be extracted into the shared module.
+  localModuleLevelBindings.delete('Route')
+
+  if (localModuleLevelBindings.size === 0) {
+    return new Set()
+  }
+
+  function findIndexForSplitNode(str: string) {
+    return opts.codeSplitGroupings.findIndex((group) =>
+      group.includes(str as any),
+    )
+  }
+
+  // Find the route options object — needs babel.traverse for scope resolution
+  let routeOptions: t.ObjectExpression | undefined
+
+  babel.traverse(ast, {
+    CallExpression(path) {
+      if (!t.isIdentifier(path.node.callee)) return
+      if (!splittableCreateRouteFns.includes(path.node.callee.name)) return
+
+      if (t.isCallExpression(path.parentPath.node)) {
+        const opts = resolveIdentifier(path, path.parentPath.node.arguments[0])
+        if (t.isObjectExpression(opts)) routeOptions = opts
+      } else if (t.isVariableDeclarator(path.parentPath.node)) {
+        const caller = resolveIdentifier(path, path.parentPath.node.init)
+        if (t.isCallExpression(caller)) {
+          const opts = resolveIdentifier(path, caller.arguments[0])
+          if (t.isObjectExpression(opts)) routeOptions = opts
+        }
+      }
+    },
+  })
+
+  if (!routeOptions) return new Set()
+
+  // Fast path: if fewer than 2 distinct groups are referenced by route options,
+  // nothing can be shared and we can skip the rest of the work.
+  const splitGroupsPresent = new Set<number>()
+  let hasNonSplit = false
+  for (const prop of routeOptions.properties) {
+    if (!t.isObjectProperty(prop) || !t.isIdentifier(prop.key)) continue
+    if (prop.key.name === 'codeSplitGroupings') continue
+    if (t.isIdentifier(prop.value) && prop.value.name === 'undefined') continue
+    const groupIndex = findIndexForSplitNode(prop.key.name) // -1 if non-split
+    if (groupIndex === -1) {
+      hasNonSplit = true
+    } else {
+      splitGroupsPresent.add(groupIndex)
+    }
+  }
+
+  if (!hasNonSplit && splitGroupsPresent.size < 2) return new Set()
+
+  // Build dependency graph up front — needed for transitive expansion per-property.
+  // This graph excludes `Route` (deleted above) so group attribution works correctly.
+  const declMap = buildDeclarationMap(ast)
+  const depGraph = buildDependencyGraph(declMap, localModuleLevelBindings)
+
+  // Build a second dependency graph that includes `Route` so we can detect
+  // bindings that transitively depend on it. Such bindings must NOT be
+  // extracted into the shared module because they would drag the Route
+  // singleton with them, duplicating it across modules.
+  const allLocalBindings = new Set(localModuleLevelBindings)
+  allLocalBindings.add('Route')
+  const fullDepGraph = buildDependencyGraph(declMap, allLocalBindings)
+
+  // For each route property, track which "group" it belongs to.
+  // Non-split properties get group index -1.
+  // Split properties get their codeSplitGroupings index (0, 1, ...).
+  // A binding is "shared" if it appears in 2+ distinct groups.
+  // We expand each property's refs transitively BEFORE comparing groups,
+  // so indirect refs (e.g., component: MyComp where MyComp uses `shared`)
+  // are correctly attributed.
+  const refsByGroup = new Map<string, Set<number>>()
+
+  for (const prop of routeOptions.properties) {
+    if (!t.isObjectProperty(prop) || !t.isIdentifier(prop.key)) continue
+    const key = prop.key.name
+
+    if (key === 'codeSplitGroupings') continue
+
+    const groupIndex = findIndexForSplitNode(key) // -1 if non-split
+
+    const directRefs = collectModuleLevelRefsFromNode(
+      prop.value,
+      localModuleLevelBindings,
+    )
+
+    // Expand transitively: if component references SharedComp which references
+    // `shared`, then `shared` is also attributed to component's group.
+    const allRefs = new Set(directRefs)
+    expandTransitively(allRefs, depGraph)
+
+    for (const ref of allRefs) {
+      let groups = refsByGroup.get(ref)
+      if (!groups) {
+        groups = new Set()
+        refsByGroup.set(ref, groups)
+      }
+      groups.add(groupIndex)
+    }
+  }
+
+  // Shared = bindings appearing in 2+ distinct groups
+  const shared = new Set<string>()
+  for (const [name, groups] of refsByGroup) {
+    if (groups.size >= 2) shared.add(name)
+  }
+
+  // Destructured declarators (e.g. `const { a, b } = fn()`) must be treated
+  // as a single initialization unit. Even if each binding is referenced by
+  // only one group, if *different* bindings from the same declarator are
+  // referenced by different groups, the declarator must be extracted to the
+  // shared module to avoid double initialization.
+  expandSharedDestructuredDeclarators(ast, refsByGroup, shared)
+
+  if (shared.size === 0) return shared
+
+  // If any binding from a destructured declaration is shared,
+  // all bindings from that declaration must be shared
+  expandDestructuredDeclarations(ast, shared)
+
+  // Remove shared bindings that transitively depend on `Route`.
+  // The Route singleton must stay in the reference file; extracting a
+  // binding that references it would duplicate Route in the shared module.
+  removeBindingsDependingOnRoute(shared, fullDepGraph)
+
+  return shared
+}
+
+/**
+ * If bindings from the same destructured declarator are referenced by
+ * different groups, mark all bindings from that declarator as shared.
+ */
+export function expandSharedDestructuredDeclarators(
+  ast: t.File,
+  refsByGroup: Map<string, Set<number>>,
+  shared: Set<string>,
+) {
+  for (const stmt of ast.program.body) {
+    const decl =
+      t.isExportNamedDeclaration(stmt) && stmt.declaration
+        ? stmt.declaration
+        : stmt
+
+    if (!t.isVariableDeclaration(decl)) continue
+
+    for (const declarator of decl.declarations) {
+      if (!t.isObjectPattern(declarator.id) && !t.isArrayPattern(declarator.id))
+        continue
+
+      const names = collectIdentifiersFromPattern(declarator.id)
+
+      const usedGroups = new Set<number>()
+      for (const name of names) {
+        const groups = refsByGroup.get(name)
+        if (!groups) continue
+        for (const g of groups) usedGroups.add(g)
+      }
+
+      if (usedGroups.size >= 2) {
+        for (const name of names) {
+          shared.add(name)
+        }
+      }
+    }
+  }
+}
+
+/**
+ * Collect locally-declared module-level binding names from a statement.
+ * Pure node inspection, no traversal.
+ */
+export function collectLocalBindingsFromStatement(
+  node: t.Statement | t.ModuleDeclaration,
+  bindings: Set<string>,
+) {
+  const decl =
+    t.isExportNamedDeclaration(node) && node.declaration
+      ? node.declaration
+      : node
+
+  if (t.isVariableDeclaration(decl)) {
+    for (const declarator of decl.declarations) {
+      for (const name of collectIdentifiersFromPattern(declarator.id)) {
+        bindings.add(name)
+      }
+    }
+  } else if (t.isFunctionDeclaration(decl) && decl.id) {
+    bindings.add(decl.id.name)
+  } else if (t.isClassDeclaration(decl) && decl.id) {
+    bindings.add(decl.id.name)
+  }
+}
+
+/**
+ * Collect direct module-level binding names referenced from a given AST node.
+ * Uses a simple recursive walk instead of babel.traverse.
+ */
+export function collectModuleLevelRefsFromNode(
+  node: t.Node,
+  localModuleLevelBindings: Set<string>,
+): Set<string> {
+  const allIds = collectIdentifiersFromNode(node)
+  const refs = new Set<string>()
+  for (const name of allIds) {
+    if (localModuleLevelBindings.has(name)) refs.add(name)
+  }
+  return refs
+}
+
+/**
+ * Expand the shared set transitively using a prebuilt dependency graph.
+ * No AST traversals — pure graph BFS.
+ */
+export function expandTransitively(
+  shared: Set<string>,
+  depGraph: Map<string, Set<string>>,
+) {
+  const queue = [...shared]
+  const visited = new Set<string>()
+
+  while (queue.length > 0) {
+    const name = queue.pop()!
+    if (visited.has(name)) continue
+    visited.add(name)
+
+    const deps = depGraph.get(name)
+    if (!deps) continue
+
+    for (const dep of deps) {
+      if (!shared.has(dep)) {
+        shared.add(dep)
+        queue.push(dep)
+      }
+    }
+  }
+}
+
+/**
+ * Remove any bindings from `shared` that transitively depend on `Route`.
+ * The Route singleton must remain in the reference file; if a shared binding
+ * references it (directly or transitively), extracting that binding would
+ * duplicate Route in the shared module.
+ *
+ * Uses `depGraph` which must include `Route` as a node so the dependency
+ * chain is visible.
+ */
+export function removeBindingsDependingOnRoute(
+  shared: Set<string>,
+  depGraph: Map<string, Set<string>>,
+) {
+  const reverseGraph = new Map<string, Set<string>>()
+  for (const [name, deps] of depGraph) {
+    for (const dep of deps) {
+      let parents = reverseGraph.get(dep)
+      if (!parents) {
+        parents = new Set<string>()
+        reverseGraph.set(dep, parents)
+      }
+      parents.add(name)
+    }
+  }
+
+  // Walk backwards from Route to find all bindings that can reach it.
+  const visited = new Set<string>()
+  const queue = ['Route']
+  while (queue.length > 0) {
+    const cur = queue.pop()!
+    if (visited.has(cur)) continue
+    visited.add(cur)
+
+    const parents = reverseGraph.get(cur)
+    if (!parents) continue
+    for (const parent of parents) {
+      if (!visited.has(parent)) queue.push(parent)
+    }
+  }
+
+  for (const name of [...shared]) {
+    if (visited.has(name)) {
+      shared.delete(name)
+    }
+  }
+}
+
+/**
+ * If any binding from a destructured declaration is shared,
+ * ensure all bindings from that same declaration are also shared.
+ * Pure node inspection of program.body, no traversal.
+ */
+export function expandDestructuredDeclarations(
+  ast: t.File,
+  shared: Set<string>,
+) {
+  for (const stmt of ast.program.body) {
+    const decl =
+      t.isExportNamedDeclaration(stmt) && stmt.declaration
+        ? stmt.declaration
+        : stmt
+
+    if (!t.isVariableDeclaration(decl)) continue
+
+    for (const declarator of decl.declarations) {
+      if (!t.isObjectPattern(declarator.id) && !t.isArrayPattern(declarator.id))
+        continue
+
+      const names = collectIdentifiersFromPattern(declarator.id)
+      const hasShared = names.some((n) => shared.has(n))
+      if (hasShared) {
+        for (const n of names) {
+          shared.add(n)
+        }
+      }
+    }
+  }
+}
+
+/**
+ * Find which shared bindings are user-exported in the original source.
+ * These need to be re-exported from the shared module.
+ */
+function findExportedSharedBindings(
+  ast: t.File,
+  sharedBindings: Set<string>,
+): Set<string> {
+  const exported = new Set<string>()
+  for (const stmt of ast.program.body) {
+    if (!t.isExportNamedDeclaration(stmt) || !stmt.declaration) continue
+
+    if (t.isVariableDeclaration(stmt.declaration)) {
+      for (const decl of stmt.declaration.declarations) {
+        for (const name of collectIdentifiersFromPattern(decl.id)) {
+          if (sharedBindings.has(name)) exported.add(name)
+        }
+      }
+    } else if (
+      t.isFunctionDeclaration(stmt.declaration) &&
+      stmt.declaration.id
+    ) {
+      if (sharedBindings.has(stmt.declaration.id.name))
+        exported.add(stmt.declaration.id.name)
+    } else if (t.isClassDeclaration(stmt.declaration) && stmt.declaration.id) {
+      if (sharedBindings.has(stmt.declaration.id.name))
+        exported.add(stmt.declaration.id.name)
+    }
+  }
+  return exported
+}
+
+/**
+ * Remove declarations of shared bindings from the AST.
+ * Handles both plain and exported declarations, including destructured patterns.
+ * Removes the entire statement if all bindings in it are shared.
+ */
+function removeSharedDeclarations(ast: t.File, sharedBindings: Set<string>) {
+  ast.program.body = ast.program.body.filter((stmt) => {
+    const decl =
+      t.isExportNamedDeclaration(stmt) && stmt.declaration
+        ? stmt.declaration
+        : stmt
+
+    if (t.isVariableDeclaration(decl)) {
+      // Filter out declarators where all bound names are shared
+      decl.declarations = decl.declarations.filter((declarator) => {
+        const names = collectIdentifiersFromPattern(declarator.id)
+        return !names.every((n) => sharedBindings.has(n))
+      })
+      // If no declarators remain, remove the entire statement
+      if (decl.declarations.length === 0) return false
+    } else if (t.isFunctionDeclaration(decl) && decl.id) {
+      if (sharedBindings.has(decl.id.name)) return false
+    } else if (t.isClassDeclaration(decl) && decl.id) {
+      if (sharedBindings.has(decl.id.name)) return false
+    }
+
+    return true
+  })
+}
+
 export function compileCodeSplitReferenceRoute(
   opts: ParseAstOptions & {
     codeSplitGroupings: CodeSplitGroupings
@@ -112,6 +641,7 @@ export function compileCodeSplitReferenceRoute(
     filename: string
     id: string
     addHmr?: boolean
+    sharedBindings?: Set<string>
   },
 ): GeneratorResult | null {
   const ast = parseAst(opts)
@@ -135,6 +665,7 @@ export function compileCodeSplitReferenceRoute(
 
   let modified = false as boolean
   let hmrAdded = false as boolean
+  let sharedExportedNames: Set<string> | undefined
   babel.traverse(ast, {
     Program: {
       enter(programPath) {
@@ -424,6 +955,56 @@ export function compileCodeSplitReferenceRoute(
             },
           })
         }
+
+        // Handle shared bindings inside the Program visitor so we have
+        // access to programPath for cheap refIdents registration.
+        if (opts.sharedBindings && opts.sharedBindings.size > 0) {
+          sharedExportedNames = findExportedSharedBindings(
+            ast,
+            opts.sharedBindings,
+          )
+          removeSharedDeclarations(ast, opts.sharedBindings)
+
+          const sharedModuleUrl = addSharedSearchParamToFilename(opts.filename)
+
+          const sharedImportSpecifiers = [...opts.sharedBindings].map((name) =>
+            t.importSpecifier(t.identifier(name), t.identifier(name)),
+          )
+          const [sharedImportPath] = programPath.unshiftContainer(
+            'body',
+            t.importDeclaration(
+              sharedImportSpecifiers,
+              t.stringLiteral(sharedModuleUrl),
+            ),
+          )
+
+          // Register import specifier locals in refIdents so DCE can remove unused ones
+          sharedImportPath.traverse({
+            Identifier(identPath) {
+              if (
+                identPath.parentPath.isImportSpecifier() &&
+                identPath.key === 'local'
+              ) {
+                refIdents.add(identPath)
+              }
+            },
+          })
+
+          // Re-export user-exported shared bindings from the shared module
+          if (sharedExportedNames.size > 0) {
+            const reExportSpecifiers = [...sharedExportedNames].map((name) =>
+              t.exportSpecifier(t.identifier(name), t.identifier(name)),
+            )
+            programPath.pushContainer(
+              'body',
+              t.exportNamedDeclaration(
+                null,
+                reExportSpecifiers,
+                t.stringLiteral(sharedModuleUrl),
+              ),
+            )
+          }
+        }
       },
     },
   })
@@ -465,11 +1046,18 @@ export function compileCodeSplitVirtualRoute(
   opts: ParseAstOptions & {
     splitTargets: Array<SplitRouteIdentNodes>
     filename: string
+    sharedBindings?: Set<string>
   },
 ): GeneratorResult {
   const ast = parseAst(opts)
   const refIdents = findReferencedIdentifiers(ast)
 
+  // Remove shared declarations BEFORE babel.traverse so the scope never sees
+  // conflicting bindings (avoids checkBlockScopedCollisions crash in DCE)
+  if (opts.sharedBindings && opts.sharedBindings.size > 0) {
+    removeSharedDeclarations(ast, opts.sharedBindings)
+  }
+
   const intendedSplitNodes = new Set(opts.splitTargets)
 
   const knownExportedIdents = new Set<string>()
@@ -814,12 +1402,188 @@ export function compileCodeSplitVirtualRoute(
             }
           },
         })
+
+        // Add shared bindings import, registering specifiers in refIdents
+        // so DCE can remove unused ones (same pattern as import replacements above).
+        if (opts.sharedBindings && opts.sharedBindings.size > 0) {
+          const sharedImportSpecifiers = [...opts.sharedBindings].map((name) =>
+            t.importSpecifier(t.identifier(name), t.identifier(name)),
+          )
+          const sharedModuleUrl = addSharedSearchParamToFilename(
+            removeSplitSearchParamFromFilename(opts.filename),
+          )
+          const [sharedImportPath] = programPath.unshiftContainer(
+            'body',
+            t.importDeclaration(
+              sharedImportSpecifiers,
+              t.stringLiteral(sharedModuleUrl),
+            ),
+          )
+
+          sharedImportPath.traverse({
+            Identifier(identPath) {
+              if (
+                identPath.parentPath.isImportSpecifier() &&
+                identPath.key === 'local'
+              ) {
+                refIdents.add(identPath)
+              }
+            },
+          })
+        }
       },
     },
   })
 
   deadCodeElimination(ast, refIdents)
 
+  // Strip top-level expression statements that reference no locally-bound names.
+  // DCE only removes unused declarations; bare side-effect statements like
+  // `console.log(...)` survive even when the virtual file has no exports.
+  {
+    const locallyBound = new Set<string>()
+    for (const stmt of ast.program.body) {
+      collectLocalBindingsFromStatement(stmt, locallyBound)
+    }
+    ast.program.body = ast.program.body.filter((stmt) => {
+      if (!t.isExpressionStatement(stmt)) return true
+      const refs = collectIdentifiersFromNode(stmt)
+      // Keep if it references at least one locally-bound identifier
+      return [...refs].some((name) => locallyBound.has(name))
+    })
+  }
+
+  // If the body is empty after DCE, strip directive prologues too.
+  // A file containing only `'use client'` with no real code is useless.
+  if (ast.program.body.length === 0) {
+    ast.program.directives = []
+  }
+
+  return generateFromAst(ast, {
+    sourceMaps: true,
+    sourceFileName: opts.filename,
+    filename: opts.filename,
+  })
+}
+
+/**
+ * Compile the shared virtual module (`?tsr-shared=1`).
+ * Keeps only shared binding declarations, their transitive dependencies,
+ * and imports they need. Exports all shared bindings.
+ */
+export function compileCodeSplitSharedRoute(
+  opts: ParseAstOptions & {
+    sharedBindings: Set<string>
+    filename: string
+  },
+): GeneratorResult {
+  const ast = parseAst(opts)
+  const refIdents = findReferencedIdentifiers(ast)
+
+  // Collect all names that need to stay: shared bindings + their transitive deps
+  const localBindings = new Set<string>()
+  for (const node of ast.program.body) {
+    collectLocalBindingsFromStatement(node, localBindings)
+  }
+
+  // Route must never be extracted into the shared module.
+  // Excluding it from the dep graph prevents expandTransitively from
+  // pulling it in as a transitive dependency of a shared binding.
+  localBindings.delete('Route')
+
+  const declMap = buildDeclarationMap(ast)
+  const depGraph = buildDependencyGraph(declMap, localBindings)
+
+  // Start with shared bindings and expand transitively
+  const keepBindings = new Set(opts.sharedBindings)
+  keepBindings.delete('Route')
+  expandTransitively(keepBindings, depGraph)
+
+  // Remove all statements except:
+  // - Import declarations (needed for deps; DCE will clean unused ones)
+  // - Declarations of bindings in keepBindings
+  ast.program.body = ast.program.body.filter((stmt) => {
+    // Always keep imports — DCE will remove unused ones
+    if (t.isImportDeclaration(stmt)) return true
+
+    const decl =
+      t.isExportNamedDeclaration(stmt) && stmt.declaration
+        ? stmt.declaration
+        : stmt
+
+    if (t.isVariableDeclaration(decl)) {
+      // Keep declarators where at least one binding is in keepBindings
+      decl.declarations = decl.declarations.filter((declarator) => {
+        const names = collectIdentifiersFromPattern(declarator.id)
+        return names.some((n) => keepBindings.has(n))
+      })
+      if (decl.declarations.length === 0) return false
+
+      // Strip the `export` wrapper — shared module controls its own exports
+      if (t.isExportNamedDeclaration(stmt) && stmt.declaration) {
+        return true // keep for now, we'll convert below
+      }
+      return true
+    } else if (t.isFunctionDeclaration(decl) && decl.id) {
+      return keepBindings.has(decl.id.name)
+    } else if (t.isClassDeclaration(decl) && decl.id) {
+      return keepBindings.has(decl.id.name)
+    }
+
+    // Remove everything else (expression statements, other exports, etc.)
+    return false
+  })
+
+  // Convert `export const/function/class` to plain declarations
+  // (we'll add our own export statement at the end)
+  ast.program.body = ast.program.body.map((stmt) => {
+    if (t.isExportNamedDeclaration(stmt) && stmt.declaration) {
+      return stmt.declaration
+    }
+    return stmt
+  })
+
+  // Export all shared bindings (sorted for deterministic output)
+  const exportNames = [...opts.sharedBindings].sort((a, b) =>
+    a.localeCompare(b),
+  )
+  const exportSpecifiers = exportNames.map((name) =>
+    t.exportSpecifier(t.identifier(name), t.identifier(name)),
+  )
+  if (exportSpecifiers.length > 0) {
+    const exportDecl = t.exportNamedDeclaration(null, exportSpecifiers)
+    ast.program.body.push(exportDecl)
+
+    // Register export specifier locals in refIdents so DCE doesn't treat
+    // the exported bindings as unreferenced.
+    babel.traverse(ast, {
+      Program(programPath) {
+        const bodyPaths = programPath.get('body')
+        const last = bodyPaths[bodyPaths.length - 1]
+        if (last && last.isExportNamedDeclaration()) {
+          last.traverse({
+            Identifier(identPath) {
+              if (
+                identPath.parentPath.isExportSpecifier() &&
+                identPath.key === 'local'
+              ) {
+                refIdents.add(identPath)
+              }
+            },
+          })
+        }
+        programPath.stop()
+      },
+    })
+  }
+
+  deadCodeElimination(ast, refIdents)
+
+  // If the body is empty after DCE, strip directive prologues too.
+  if (ast.program.body.length === 0) {
+    ast.program.directives = []
+  }
+
   return generateFromAst(ast, {
     sourceMaps: true,
     sourceFileName: opts.filename,
diff --git a/packages/router-plugin/src/core/constants.ts b/packages/router-plugin/src/core/constants.ts
index b4d4bb940f..5659065d49 100644
--- a/packages/router-plugin/src/core/constants.ts
+++ b/packages/router-plugin/src/core/constants.ts
@@ -1,4 +1,5 @@
 export const tsrSplit = 'tsr-split'
+export const tsrShared = 'tsr-shared'
 
 export const splitRouteIdentNodes = [
   'loader',
diff --git a/packages/router-plugin/src/core/router-code-splitter-plugin.ts b/packages/router-plugin/src/core/router-code-splitter-plugin.ts
index 2dba5474a7..c0d8bf357e 100644
--- a/packages/router-plugin/src/core/router-code-splitter-plugin.ts
+++ b/packages/router-plugin/src/core/router-code-splitter-plugin.ts
@@ -8,12 +8,15 @@ import { logDiff } from '@tanstack/router-utils'
 import { getConfig, splitGroupingsSchema } from './config'
 import {
   compileCodeSplitReferenceRoute,
+  compileCodeSplitSharedRoute,
   compileCodeSplitVirtualRoute,
+  computeSharedBindings,
   detectCodeSplitGroupingsFromRoute,
 } from './code-splitter/compilers'
 import {
   defaultCodeSplitGroupings,
   splitRouteIdentNodes,
+  tsrShared,
   tsrSplit,
 } from './constants'
 import { decodeIdentifier } from './code-splitter/path-ids'
@@ -88,6 +91,10 @@ export const unpluginRouterCodeSplitterFactory: UnpluginFactory<
   }
   const isProduction = process.env.NODE_ENV === 'production'
 
+  // Map from normalized route file path → set of shared binding names.
+  // Populated by the reference compiler, consumed by virtual and shared compilers.
+  const sharedBindingsMap = new Map<string, Set<string>>()
+
   const getGlobalCodeSplitGroupings = () => {
     return (
       userConfig.codeSplittingOptions?.defaultBehavior ||
@@ -138,6 +145,17 @@ export const unpluginRouterCodeSplitterFactory: UnpluginFactory<
     const splitGroupings: CodeSplitGroupings =
       fromCode.groupings || pluginSplitBehavior || getGlobalCodeSplitGroupings()
 
+    // Compute shared bindings before compiling the reference route
+    const sharedBindings = computeSharedBindings({
+      code,
+      codeSplitGroupings: splitGroupings,
+    })
+    if (sharedBindings.size > 0) {
+      sharedBindingsMap.set(id, sharedBindings)
+    } else {
+      sharedBindingsMap.delete(id)
+    }
+
     const compiledReferenceRoute = compileCodeSplitReferenceRoute({
       code,
       codeSplitGroupings: splitGroupings,
@@ -149,6 +167,7 @@ export const unpluginRouterCodeSplitterFactory: UnpluginFactory<
         : undefined,
       addHmr:
         (userConfig.codeSplittingOptions?.addHmr ?? true) && !isProduction,
+      sharedBindings: sharedBindings.size > 0 ? sharedBindings : undefined,
     })
 
     if (compiledReferenceRoute === null) {
@@ -189,10 +208,14 @@ export const unpluginRouterCodeSplitterFactory: UnpluginFactory<
       splitRouteIdentNodes.includes(p as any),
     ) as Array<SplitRouteIdentNodes>
 
+    const baseId = id.split('?')[0]!
+    const resolvedSharedBindings = sharedBindingsMap.get(baseId)
+
     const result = compileCodeSplitVirtualRoute({
       code,
       filename: id,
       splitTargets: grouping,
+      sharedBindings: resolvedSharedBindings,
     })
 
     if (debug) {
@@ -216,7 +239,7 @@ export const unpluginRouterCodeSplitterFactory: UnpluginFactory<
       transform: {
         filter: {
           id: {
-            exclude: tsrSplit,
+            exclude: [tsrSplit, tsrShared],
             // this is necessary for webpack / rspack to avoid matching .html files
             include: /\.(m|c)?(j|t)sx?$/,
           },
@@ -325,6 +348,60 @@ export const unpluginRouterCodeSplitterFactory: UnpluginFactory<
           return handleCompilingVirtualFile(code, normalizedId)
         },
       },
+
+      vite: {
+        applyToEnvironment(environment) {
+          if (userConfig.plugin?.vite?.environmentName) {
+            return userConfig.plugin.vite.environmentName === environment.name
+          }
+          return true
+        },
+      },
+    },
+    {
+      name: 'tanstack-router:code-splitter:compile-shared-file',
+      enforce: 'pre',
+
+      transform: {
+        filter: {
+          id: /tsr-shared/,
+        },
+        handler(code, id) {
+          const url = pathToFileURL(id)
+          url.searchParams.delete('v')
+          const normalizedId = normalizePath(fileURLToPath(url))
+          const [baseId] = normalizedId.split('?')
+
+          if (!baseId) return null
+
+          const sharedBindings = sharedBindingsMap.get(baseId)
+          if (!sharedBindings || sharedBindings.size === 0) return null
+
+          if (debug) console.info('Compiling Shared Module: ', id)
+
+          const result = compileCodeSplitSharedRoute({
+            code,
+            sharedBindings,
+            filename: normalizedId,
+          })
+
+          if (debug) {
+            logDiff(code, result.code)
+            console.log('Output:\n', result.code + '\n\n')
+          }
+
+          return result
+        },
+      },
+
+      vite: {
+        applyToEnvironment(environment) {
+          if (userConfig.plugin?.vite?.environmentName) {
+            return userConfig.plugin.vite.environmentName === environment.name
+          }
+          return true
+        },
+      },
     },
   ]
 }
diff --git a/packages/router-plugin/tests/code-splitter.test.ts b/packages/router-plugin/tests/code-splitter.test.ts
index 6edf37b5f1..c27b45b7ae 100644
--- a/packages/router-plugin/tests/code-splitter.test.ts
+++ b/packages/router-plugin/tests/code-splitter.test.ts
@@ -4,7 +4,9 @@ import { describe, expect, it } from 'vitest'
 
 import {
   compileCodeSplitReferenceRoute,
+  compileCodeSplitSharedRoute,
   compileCodeSplitVirtualRoute,
+  computeSharedBindings,
 } from '../src/core/code-splitter/compilers'
 import { createIdentifier } from '../src/core/code-splitter/path-ids'
 import { defaultCodeSplitGroupings } from '../src/core/constants'
@@ -58,6 +60,11 @@ describe('code-splitter works', () => {
             const file = await readFile(path.join(dirs.files, filename))
             const code = file.toString()
 
+            const sharedBindings = computeSharedBindings({
+              code,
+              codeSplitGroupings: grouping,
+            })
+
             const compileResult = compileCodeSplitReferenceRoute({
               code,
               filename,
@@ -65,6 +72,8 @@ describe('code-splitter works', () => {
               addHmr: false,
               codeSplitGroupings: grouping,
               targetFramework: framework,
+              sharedBindings:
+                sharedBindings.size > 0 ? sharedBindings : undefined,
             })
 
             await expect(compileResult?.code || code).toMatchFileSnapshot(
@@ -79,6 +88,11 @@ describe('code-splitter works', () => {
             const file = await readFile(path.join(dirs.files, filename))
             const code = file.toString()
 
+            const sharedBindings = computeSharedBindings({
+              code,
+              codeSplitGroupings: grouping,
+            })
+
             for (const targets of grouping) {
               const ident = createIdentifier(targets)
 
@@ -86,6 +100,8 @@ describe('code-splitter works', () => {
                 code,
                 filename: `${filename}?${ident}`,
                 splitTargets: targets,
+                sharedBindings:
+                  sharedBindings.size > 0 ? sharedBindings : undefined,
               })
 
               const snapshotFilename = path.join(
@@ -99,7 +115,122 @@ describe('code-splitter works', () => {
             }
           },
         )
+
+        it.each(filenames)(
+          `should compile "shared" for "%s"`,
+          async (filename) => {
+            const file = await readFile(path.join(dirs.files, filename))
+            const code = file.toString()
+
+            const sharedBindings = computeSharedBindings({
+              code,
+              codeSplitGroupings: grouping,
+            })
+
+            const snapshotFilename = path.join(
+              dirs.snapshots,
+              groupName,
+              `${filename.replace('.tsx', '')}@shared.tsx`,
+            )
+
+            if (sharedBindings.size === 0) {
+              // No shared module — snapshot should be empty string
+              await expect('').toMatchFileSnapshot(snapshotFilename)
+              return
+            }
+
+            const sharedResult = compileCodeSplitSharedRoute({
+              code,
+              sharedBindings,
+              filename: `${filename}?tsr-shared=1`,
+            })
+
+            await expect(sharedResult.code).toMatchFileSnapshot(
+              snapshotFilename,
+            )
+          },
+        )
       },
     )
   })
 })
+
+describe('computeSharedBindings fast paths', () => {
+  it('returns empty when only one split group is present (default groupings)', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const shared = 42
+export const Route = createFileRoute('/')({
+  component: () => shared,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultCodeSplitGroupings,
+    })
+    expect(result.size).toBe(0)
+  })
+
+  it('returns empty when all split props are in the same group', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const shared = 42
+export const Route = createFileRoute('/')({
+  component: () => shared,
+  loader: () => shared,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: [['component', 'loader']],
+    })
+    expect(result.size).toBe(0)
+  })
+
+  it('returns empty when all route option values are undefined', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+export const Route = createFileRoute('/')({
+  component: undefined,
+  errorComponent: undefined,
+  notFoundComponent: undefined,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultCodeSplitGroupings,
+    })
+    expect(result.size).toBe(0)
+  })
+
+  it('returns empty when no local bindings exist (only imports + Route)', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+export const Route = createFileRoute('/')({
+  component: () => <div>hello</div>,
+  errorComponent: () => <div>error</div>,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultCodeSplitGroupings,
+    })
+    expect(result.size).toBe(0)
+  })
+
+  it('does not fast-path when there is a non-split and a split group', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const shared = 42
+export const Route = createFileRoute('/')({
+  component: () => shared,
+  beforeLoad: () => shared,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultCodeSplitGroupings,
+    })
+    expect(result).toContain('shared')
+  })
+})
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/arrow-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/arrow-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/boolean-null-literals@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/boolean-null-literals@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/chinese@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/chinese@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/circular-reference-arrow-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/circular-reference-arrow-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/circular-reference-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/circular-reference-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/conditional-properties@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/conditional-properties@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-multiple@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-multiple@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-nested@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-nested@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-react-memo-imported-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-react-memo-imported-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-route-options-defaults.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-route-options-defaults.tsx
index 7bb274e5bc..7c54a2c145 100644
--- a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-route-options-defaults.tsx
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-route-options-defaults.tsx
@@ -1,23 +1,7 @@
+import { loader } from "destructured-route-options-defaults.tsx?tsr-shared=1";
 const $$splitComponentImporter = () => import('destructured-route-options-defaults.tsx?tsr-split=component');
 import { lazyRouteComponent } from '@tanstack/react-router';
 import { createFileRoute } from '@tanstack/react-router';
-function defaultLoader() {
-  return {
-    message: 'default'
-  };
-}
-const createBits = () => ({
-  component: ActualComponent,
-  loader: () => ({
-    message: 'hello'
-  })
-});
-const {
-  loader = defaultLoader
-} = createBits();
-function ActualComponent() {
-  return <div>About</div>;
-}
 export const Route = createFileRoute('/about')({
   component: lazyRouteComponent($$splitComponentImporter, 'component'),
   loader
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-route-options-defaults@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-route-options-defaults@component.tsx
index b03091e7e3..c73696ff32 100644
--- a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-route-options-defaults@component.tsx
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-route-options-defaults@component.tsx
@@ -1,16 +1,2 @@
-function DefaultComponent() {
-  return <div>Default</div>;
-}
-const createBits = () => ({
-  component: ActualComponent,
-  loader: () => ({
-    message: 'hello'
-  })
-});
-const {
-  component: MyComponent = DefaultComponent
-} = createBits();
-function ActualComponent() {
-  return <div>About</div>;
-}
+import { MyComponent } from "destructured-route-options-defaults.tsx?tsr-shared=1";
 export { MyComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-route-options-defaults@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-route-options-defaults@shared.tsx
new file mode 100644
index 0000000000..fdc9acef5b
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-route-options-defaults@shared.tsx
@@ -0,0 +1,22 @@
+function defaultLoader() {
+  return {
+    message: 'default'
+  };
+}
+function DefaultComponent() {
+  return <div>Default</div>;
+}
+const createBits = () => ({
+  component: ActualComponent,
+  loader: () => ({
+    message: 'hello'
+  })
+});
+const {
+  component: MyComponent = DefaultComponent,
+  loader = defaultLoader
+} = createBits();
+function ActualComponent() {
+  return <div>About</div>;
+}
+export { ActualComponent, createBits, DefaultComponent, defaultLoader, loader, MyComponent };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructuring@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructuring@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/directive-prologue.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/directive-prologue.tsx
new file mode 100644
index 0000000000..68f8be0364
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/directive-prologue.tsx
@@ -0,0 +1,8 @@
+'use client';
+
+const $$splitComponentImporter = () => import('directive-prologue.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/directive')({
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/directive-prologue@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/directive-prologue@component.tsx
new file mode 100644
index 0000000000..ce7cd5e5ee
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/directive-prologue@component.tsx
@@ -0,0 +1,6 @@
+'use client';
+
+const SplitComponent = () => {
+  return <div>directive preserved</div>;
+};
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/directive-prologue@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/directive-prologue@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/directive-prologue@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/directive-prologue@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/directive-prologue@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/directive-prologue@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/explicit-undefined-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/explicit-undefined-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/export-default-component-and-normal-notFound@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/export-default-component-and-normal-notFound@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/export-default-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/export-default-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/function-as-parameter@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/function-as-parameter@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/function-declaration@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/function-declaration@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/importAttribute@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/importAttribute@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/imported-default-component-destructured-loader@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/imported-default-component-destructured-loader@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/imported-default-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/imported-default-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/imported-errorComponent@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/imported-errorComponent@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/imported-notFoundComponent@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/imported-notFoundComponent@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/imported-pendingComponent@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/imported-pendingComponent@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/imported@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/imported@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@component.tsx
index 4b18cae17a..58ccfb2903 100644
--- a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@component.tsx
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@component.tsx
@@ -7,7 +7,6 @@ const Button = (props: {
   return <button>{props.children}</button>;
 };
 import { Route } from "inline.tsx";
-Route.addChildren([]);
 import { test } from "inline.tsx";
 const SplitComponent = () => {
   return <div className="p-2">
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@errorComponent.tsx
index 4a822161e1..9236af6021 100644
--- a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@errorComponent.tsx
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@errorComponent.tsx
@@ -1,3 +1,2 @@
 import * as React from 'react';
-import { Route } from "inline.tsx";
-Route.addChildren([]);
\ No newline at end of file
+import { Route } from "inline.tsx";
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@notFoundComponent.tsx
index 4a822161e1..9236af6021 100644
--- a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@notFoundComponent.tsx
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@notFoundComponent.tsx
@@ -1,3 +1,2 @@
 import * as React from 'react';
-import { Route } from "inline.tsx";
-Route.addChildren([]);
\ No newline at end of file
+import { Route } from "inline.tsx";
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/random-number@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/random-number@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/react-memo-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/react-memo-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/react-memo-imported-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/react-memo-imported-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-export-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-export-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-const@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-const@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-destructured@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-destructured@component.tsx
index e69de29bb2..a6d57afe77 100644
--- a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-destructured@component.tsx
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-destructured@component.tsx
@@ -0,0 +1,2 @@
+import { AboutComponent } from "retain-exports-destructured.tsx?tsr-shared=1";
+export { AboutComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-destructured@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-destructured@shared.tsx
new file mode 100644
index 0000000000..b03a4eb83a
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-destructured@shared.tsx
@@ -0,0 +1,14 @@
+const createBits = () => ({
+  component: AboutComponentImpl,
+  loader: () => ({
+    message: 'hello'
+  })
+});
+const {
+  component: AboutComponent,
+  loader
+} = createBits();
+function AboutComponentImpl() {
+  return <div>About</div>;
+}
+export { AboutComponent, AboutComponentImpl, createBits, loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-loader@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-loader@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-class.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-class.tsx
new file mode 100644
index 0000000000..6e2f0229e4
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-class.tsx
@@ -0,0 +1,10 @@
+import { store } from "shared-class.tsx?tsr-shared=1";
+const $$splitComponentImporter = () => import('shared-class.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/store')({
+  loader: async () => {
+    store.set('items', await fetch('/api'));
+  },
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-class@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-class@component.tsx
new file mode 100644
index 0000000000..6a38b10ff8
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-class@component.tsx
@@ -0,0 +1,3 @@
+import { store } from "shared-class.tsx?tsr-shared=1";
+const SplitComponent = () => <div>{store.get('items')}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-class@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-class@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-class@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-class@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-class@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-class@shared.tsx
new file mode 100644
index 0000000000..18c40bafb6
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-class@shared.tsx
@@ -0,0 +1,11 @@
+class DataStore {
+  data = new Map();
+  get(k: string) {
+    return this.data.get(k);
+  }
+  set(k: string, v: unknown) {
+    this.data.set(k, v);
+  }
+}
+const store = new DataStore();
+export { DataStore, store };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured-export.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured-export.tsx
new file mode 100644
index 0000000000..9453dbfbda
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured-export.tsx
@@ -0,0 +1,9 @@
+import { apiUrl } from "shared-destructured-export.tsx?tsr-shared=1";
+const $$splitComponentImporter = () => import('shared-destructured-export.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/config')({
+  loader: async () => fetch(apiUrl),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
+export { apiUrl, timeout } from "shared-destructured-export.tsx?tsr-shared=1";
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured-export@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured-export@component.tsx
new file mode 100644
index 0000000000..16b288ac5f
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured-export@component.tsx
@@ -0,0 +1,3 @@
+import { timeout } from "shared-destructured-export.tsx?tsr-shared=1";
+const SplitComponent = () => <div>Timeout: {timeout}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured-export@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured-export@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured-export@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured-export@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured-export@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured-export@shared.tsx
new file mode 100644
index 0000000000..f0bfd70add
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured-export@shared.tsx
@@ -0,0 +1,11 @@
+const {
+  apiUrl,
+  timeout
+} = getConfig();
+function getConfig() {
+  return {
+    apiUrl: '/api',
+    timeout: 5000
+  };
+}
+export { apiUrl, getConfig, timeout };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured.tsx
new file mode 100644
index 0000000000..3019454516
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured.tsx
@@ -0,0 +1,8 @@
+import { apiUrl } from "shared-destructured.tsx?tsr-shared=1";
+const $$splitComponentImporter = () => import('shared-destructured.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/config')({
+  loader: async () => fetch(apiUrl),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured@component.tsx
new file mode 100644
index 0000000000..5c0182e61a
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured@component.tsx
@@ -0,0 +1,3 @@
+import { timeout } from "shared-destructured.tsx?tsr-shared=1";
+const SplitComponent = () => <div>Timeout: {timeout}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured@shared.tsx
new file mode 100644
index 0000000000..f0bfd70add
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured@shared.tsx
@@ -0,0 +1,11 @@
+const {
+  apiUrl,
+  timeout
+} = getConfig();
+function getConfig() {
+  return {
+    apiUrl: '/api',
+    timeout: 5000
+  };
+}
+export { apiUrl, getConfig, timeout };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-exported.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-exported.tsx
new file mode 100644
index 0000000000..c2eb8b1012
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-exported.tsx
@@ -0,0 +1,13 @@
+import { queryOptions } from "shared-exported.tsx?tsr-shared=1";
+const $$splitComponentImporter = () => import('shared-exported.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/query')({
+  loader: async () => {
+    return {
+      staleTime: queryOptions.staleTime
+    };
+  },
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
+export { queryOptions } from "shared-exported.tsx?tsr-shared=1";
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-exported@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-exported@component.tsx
new file mode 100644
index 0000000000..b020b5cadf
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-exported@component.tsx
@@ -0,0 +1,3 @@
+import { queryOptions } from "shared-exported.tsx?tsr-shared=1";
+const SplitComponent = () => <div>GC: {queryOptions.gcTime}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-exported@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-exported@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-exported@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-exported@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-exported@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-exported@shared.tsx
new file mode 100644
index 0000000000..a3f91b85bb
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-exported@shared.tsx
@@ -0,0 +1,5 @@
+const queryOptions = {
+  staleTime: 5000,
+  gcTime: 10000
+};
+export { queryOptions };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-function.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-function.tsx
new file mode 100644
index 0000000000..7372ff4b07
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-function.tsx
@@ -0,0 +1,14 @@
+import { getCached, cache } from "shared-function.tsx?tsr-shared=1";
+const $$splitComponentImporter = () => import('shared-function.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+function setCached(key: string, val: unknown) {
+  cache.set(key, val);
+}
+export const Route = createFileRoute('/cached')({
+  loader: async () => {
+    setCached('data', await fetch('/api').then(r => r.json()));
+    return getCached('data');
+  },
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-function@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-function@component.tsx
new file mode 100644
index 0000000000..571bd9356a
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-function@component.tsx
@@ -0,0 +1,3 @@
+import { getCached } from "shared-function.tsx?tsr-shared=1";
+const SplitComponent = () => <div>{JSON.stringify(getCached('data'))}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-function@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-function@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-function@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-function@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-function@shared.tsx
new file mode 100644
index 0000000000..27d2cf03f1
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-function@shared.tsx
@@ -0,0 +1,5 @@
+const cache = new Map();
+function getCached(key: string) {
+  return cache.get(key);
+}
+export { cache, getCached };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-imported-binding.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-imported-binding.tsx
new file mode 100644
index 0000000000..c3e284c081
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-imported-binding.tsx
@@ -0,0 +1,8 @@
+const $$splitComponentImporter = () => import('shared-imported-binding.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+import { sharedUtil } from '../utils';
+export const Route = createFileRoute('/imported')({
+  loader: async () => sharedUtil('load'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-imported-binding@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-imported-binding@component.tsx
new file mode 100644
index 0000000000..0a835ae063
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-imported-binding@component.tsx
@@ -0,0 +1,3 @@
+import { sharedUtil } from '../utils';
+const SplitComponent = () => <div>{sharedUtil('render')}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-imported-binding@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-imported-binding@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-imported-binding@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-imported-binding@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-imported-binding@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-imported-binding@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-indirect-ref.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-indirect-ref.tsx
new file mode 100644
index 0000000000..889dd57cf0
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-indirect-ref.tsx
@@ -0,0 +1,13 @@
+import { state, getCount } from "shared-indirect-ref.tsx?tsr-shared=1";
+const $$splitComponentImporter = () => import('shared-indirect-ref.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/shared-indirect')({
+  loader: () => {
+    state.count++;
+    return {
+      count: getCount()
+    };
+  },
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-indirect-ref@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-indirect-ref@component.tsx
new file mode 100644
index 0000000000..62995e7fd8
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-indirect-ref@component.tsx
@@ -0,0 +1,7 @@
+import { state, getCount } from "shared-indirect-ref.tsx?tsr-shared=1";
+function SharedComponent() {
+  return <div>
+      {getCount()} - {state.count}
+    </div>;
+}
+export { SharedComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-indirect-ref@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-indirect-ref@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-indirect-ref@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-indirect-ref@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-indirect-ref@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-indirect-ref@shared.tsx
new file mode 100644
index 0000000000..7e7e811ba8
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-indirect-ref@shared.tsx
@@ -0,0 +1,7 @@
+const state = {
+  count: 0
+};
+function getCount() {
+  return state.count;
+}
+export { getCount, state };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-jsx-component-ref.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-jsx-component-ref.tsx
new file mode 100644
index 0000000000..728caca361
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-jsx-component-ref.tsx
@@ -0,0 +1,9 @@
+import { shared } from "shared-jsx-component-ref.tsx?tsr-shared=1";
+const $$splitComponentImporter = () => import('shared-jsx-component-ref.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+// @ts-nocheck
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/jsx')({
+  loader: () => shared,
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-jsx-component-ref@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-jsx-component-ref@component.tsx
new file mode 100644
index 0000000000..52ecb6d474
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-jsx-component-ref@component.tsx
@@ -0,0 +1,5 @@
+import { shared } from "shared-jsx-component-ref.tsx?tsr-shared=1"; // @ts-nocheck
+function SharedComponent() {
+  return <div>{shared}</div>;
+}
+export { SharedComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-jsx-component-ref@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-jsx-component-ref@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-jsx-component-ref@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-jsx-component-ref@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-jsx-component-ref@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-jsx-component-ref@shared.tsx
new file mode 100644
index 0000000000..d5cc2cf990
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-jsx-component-ref@shared.tsx
@@ -0,0 +1,4 @@
+// @ts-nocheck
+
+const shared = 1;
+export { shared };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-none.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-none.tsx
new file mode 100644
index 0000000000..dd352bfc41
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-none.tsx
@@ -0,0 +1,8 @@
+const $$splitComponentImporter = () => import('shared-none.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+const loaderHelper = () => fetch('/api');
+export const Route = createFileRoute('/clean')({
+  loader: async () => loaderHelper(),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-none@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-none@component.tsx
new file mode 100644
index 0000000000..701deeedeb
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-none@component.tsx
@@ -0,0 +1,5 @@
+const ComponentHelper = () => <span>helper</span>;
+const SplitComponent = () => <div>
+      <ComponentHelper />
+    </div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-none@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-none@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-none@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-none@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-none@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-none@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-referencing-route.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-referencing-route.tsx
new file mode 100644
index 0000000000..f82ac5b900
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-referencing-route.tsx
@@ -0,0 +1,16 @@
+import { HEADER } from "shared-referencing-route.tsx?tsr-shared=1";
+const $$splitComponentImporter = () => import('shared-referencing-route.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+function usePageTitle() {
+  return `${HEADER} - ${Route.fullPath}`;
+}
+export const Route = createFileRoute('/about')({
+  loader: async () => {
+    const title = usePageTitle();
+    return {
+      title
+    };
+  },
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-referencing-route@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-referencing-route@component.tsx
new file mode 100644
index 0000000000..2cb2cdb68c
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-referencing-route@component.tsx
@@ -0,0 +1,10 @@
+import { HEADER } from "shared-referencing-route.tsx?tsr-shared=1";
+function usePageTitle() {
+  return `${HEADER} - ${Route.fullPath}`;
+}
+import { Route } from "shared-referencing-route.tsx";
+const SplitComponent = () => {
+  const title = usePageTitle();
+  return <div>{title}</div>;
+};
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-referencing-route@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-referencing-route@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-referencing-route@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-referencing-route@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-referencing-route@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-referencing-route@shared.tsx
new file mode 100644
index 0000000000..cc2d01424c
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-referencing-route@shared.tsx
@@ -0,0 +1,2 @@
+const HEADER = 'Page';
+export { HEADER };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-transitive.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-transitive.tsx
new file mode 100644
index 0000000000..ce5a10c47c
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-transitive.tsx
@@ -0,0 +1,11 @@
+import { config } from "shared-transitive.tsx?tsr-shared=1";
+const $$splitComponentImporter = () => import('shared-transitive.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+const fetcher = (path: string) => fetch(`${config.url}${path}`);
+export const Route = createFileRoute('/api')({
+  loader: async () => {
+    return fetcher('/data');
+  },
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-transitive@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-transitive@component.tsx
new file mode 100644
index 0000000000..7a3a74048e
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-transitive@component.tsx
@@ -0,0 +1,3 @@
+import { config } from "shared-transitive.tsx?tsr-shared=1";
+const SplitComponent = () => <div>Timeout: {config.timeout}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-transitive@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-transitive@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-transitive@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-transitive@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-transitive@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-transitive@shared.tsx
new file mode 100644
index 0000000000..8bec4a1d55
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-transitive@shared.tsx
@@ -0,0 +1,6 @@
+const BASE_URL = 'https://api.example.com';
+const config = {
+  url: BASE_URL,
+  timeout: 5000
+};
+export { BASE_URL, config };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-variable.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-variable.tsx
new file mode 100644
index 0000000000..c0c02cec46
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-variable.tsx
@@ -0,0 +1,13 @@
+import { collection } from "shared-variable.tsx?tsr-shared=1";
+const $$splitComponentImporter = () => import('shared-variable.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/todos')({
+  loader: async () => {
+    await collection.preload();
+    return {
+      data: 'loaded'
+    };
+  },
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-variable@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-variable@component.tsx
new file mode 100644
index 0000000000..d149922fbc
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-variable@component.tsx
@@ -0,0 +1,3 @@
+import { collection } from "shared-variable.tsx?tsr-shared=1";
+const SplitComponent = () => <div>{collection.name}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-variable@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-variable@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-variable@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-variable@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-variable@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-variable@shared.tsx
new file mode 100644
index 0000000000..8a0560d5b9
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-variable@shared.tsx
@@ -0,0 +1,5 @@
+const collection = {
+  name: 'todos',
+  preload: async () => {}
+};
+export { collection };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-with-side-effect.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-with-side-effect.tsx
new file mode 100644
index 0000000000..cba0c7770b
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-with-side-effect.tsx
@@ -0,0 +1,11 @@
+import { registry } from "shared-with-side-effect.tsx?tsr-shared=1";
+const $$splitComponentImporter = () => import('shared-with-side-effect.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+console.log('registry created');
+export const Route = createFileRoute('/fx')({
+  loader: async () => {
+    registry.set('loaded', true);
+  },
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-with-side-effect@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-with-side-effect@component.tsx
new file mode 100644
index 0000000000..d953af00fa
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-with-side-effect@component.tsx
@@ -0,0 +1,3 @@
+import { registry } from "shared-with-side-effect.tsx?tsr-shared=1";
+const SplitComponent = () => <div>{registry.size}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-with-side-effect@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-with-side-effect@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-with-side-effect@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-with-side-effect@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-with-side-effect@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-with-side-effect@shared.tsx
new file mode 100644
index 0000000000..f26c656fdd
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-with-side-effect@shared.tsx
@@ -0,0 +1,2 @@
+const registry = new Map();
+export { registry };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/undefined-literals@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/undefined-literals@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/useStateDestructure@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/useStateDestructure@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/using@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/using@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/arrow-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/arrow-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/boolean-null-literals@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/boolean-null-literals@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/chinese@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/chinese@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/circular-reference-arrow-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/circular-reference-arrow-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/circular-reference-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/circular-reference-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/conditional-properties@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/conditional-properties@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export-multiple@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export-multiple@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export-nested@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export-nested@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-react-memo-imported-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-react-memo-imported-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-route-options-defaults@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-route-options-defaults@component---errorComponent---notFoundComponent---pendingComponent.tsx
index b03091e7e3..c73696ff32 100644
--- a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-route-options-defaults@component---errorComponent---notFoundComponent---pendingComponent.tsx
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-route-options-defaults@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -1,16 +1,2 @@
-function DefaultComponent() {
-  return <div>Default</div>;
-}
-const createBits = () => ({
-  component: ActualComponent,
-  loader: () => ({
-    message: 'hello'
-  })
-});
-const {
-  component: MyComponent = DefaultComponent
-} = createBits();
-function ActualComponent() {
-  return <div>About</div>;
-}
+import { MyComponent } from "destructured-route-options-defaults.tsx?tsr-shared=1";
 export { MyComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-route-options-defaults@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-route-options-defaults@loader.tsx
index dc61cde518..99d9619b91 100644
--- a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-route-options-defaults@loader.tsx
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-route-options-defaults@loader.tsx
@@ -1,18 +1,2 @@
-function defaultLoader() {
-  return {
-    message: 'default'
-  };
-}
-const createBits = () => ({
-  component: ActualComponent,
-  loader: () => ({
-    message: 'hello'
-  })
-});
-const {
-  loader = defaultLoader
-} = createBits();
-function ActualComponent() {
-  return <div>About</div>;
-}
+import { loader } from "destructured-route-options-defaults.tsx?tsr-shared=1";
 export { loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-route-options-defaults@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-route-options-defaults@shared.tsx
new file mode 100644
index 0000000000..fdc9acef5b
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-route-options-defaults@shared.tsx
@@ -0,0 +1,22 @@
+function defaultLoader() {
+  return {
+    message: 'default'
+  };
+}
+function DefaultComponent() {
+  return <div>Default</div>;
+}
+const createBits = () => ({
+  component: ActualComponent,
+  loader: () => ({
+    message: 'hello'
+  })
+});
+const {
+  component: MyComponent = DefaultComponent,
+  loader = defaultLoader
+} = createBits();
+function ActualComponent() {
+  return <div>About</div>;
+}
+export { ActualComponent, createBits, DefaultComponent, defaultLoader, loader, MyComponent };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructuring@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructuring@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/directive-prologue.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/directive-prologue.tsx
new file mode 100644
index 0000000000..12d3529331
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/directive-prologue.tsx
@@ -0,0 +1,8 @@
+'use client';
+
+const $$splitComponentImporter = () => import('directive-prologue.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/directive')({
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/directive-prologue@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/directive-prologue@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..ce7cd5e5ee
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/directive-prologue@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,6 @@
+'use client';
+
+const SplitComponent = () => {
+  return <div>directive preserved</div>;
+};
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/directive-prologue@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/directive-prologue@loader.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/directive-prologue@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/directive-prologue@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/explicit-undefined-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/explicit-undefined-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/export-default-component-and-normal-notFound@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/export-default-component-and-normal-notFound@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/export-default-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/export-default-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/function-as-parameter@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/function-as-parameter@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/function-declaration@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/function-declaration@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/importAttribute@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/importAttribute@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/imported-default-component-destructured-loader@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/imported-default-component-destructured-loader@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/imported-default-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/imported-default-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/imported-errorComponent@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/imported-errorComponent@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/imported-notFoundComponent@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/imported-notFoundComponent@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/imported-pendingComponent@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/imported-pendingComponent@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/imported@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/imported@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/inline@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/inline@component---errorComponent---notFoundComponent---pendingComponent.tsx
index 4b18cae17a..58ccfb2903 100644
--- a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/inline@component---errorComponent---notFoundComponent---pendingComponent.tsx
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/inline@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -7,7 +7,6 @@ const Button = (props: {
   return <button>{props.children}</button>;
 };
 import { Route } from "inline.tsx";
-Route.addChildren([]);
 import { test } from "inline.tsx";
 const SplitComponent = () => {
   return <div className="p-2">
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/inline@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/inline@loader.tsx
index 4a822161e1..9236af6021 100644
--- a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/inline@loader.tsx
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/inline@loader.tsx
@@ -1,3 +1,2 @@
 import * as React from 'react';
-import { Route } from "inline.tsx";
-Route.addChildren([]);
\ No newline at end of file
+import { Route } from "inline.tsx";
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/inline@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/inline@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/random-number@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/random-number@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/react-memo-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/react-memo-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/react-memo-imported-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/react-memo-imported-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-export-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-export-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-const@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-const@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-destructured@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-destructured@component---errorComponent---notFoundComponent---pendingComponent.tsx
index e69de29bb2..a6d57afe77 100644
--- a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-destructured@component---errorComponent---notFoundComponent---pendingComponent.tsx
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-destructured@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,2 @@
+import { AboutComponent } from "retain-exports-destructured.tsx?tsr-shared=1";
+export { AboutComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-destructured@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-destructured@loader.tsx
index 43108700f5..e8d771ea44 100644
--- a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-destructured@loader.tsx
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-destructured@loader.tsx
@@ -1 +1,2 @@
-export { SplitLoader as loader };
\ No newline at end of file
+import { loader } from "retain-exports-destructured.tsx?tsr-shared=1";
+export { loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-destructured@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-destructured@shared.tsx
new file mode 100644
index 0000000000..b03a4eb83a
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-destructured@shared.tsx
@@ -0,0 +1,14 @@
+const createBits = () => ({
+  component: AboutComponentImpl,
+  loader: () => ({
+    message: 'hello'
+  })
+});
+const {
+  component: AboutComponent,
+  loader
+} = createBits();
+function AboutComponentImpl() {
+  return <div>About</div>;
+}
+export { AboutComponent, AboutComponentImpl, createBits, loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-loader@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-loader@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-class.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-class.tsx
new file mode 100644
index 0000000000..da068daa17
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-class.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-class.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-class.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/store')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-class@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-class@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..6a38b10ff8
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-class@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,3 @@
+import { store } from "shared-class.tsx?tsr-shared=1";
+const SplitComponent = () => <div>{store.get('items')}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-class@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-class@loader.tsx
new file mode 100644
index 0000000000..f91799f3c8
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-class@loader.tsx
@@ -0,0 +1,5 @@
+import { store } from "shared-class.tsx?tsr-shared=1";
+const SplitLoader = async () => {
+  store.set('items', await fetch('/api'));
+};
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-class@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-class@shared.tsx
new file mode 100644
index 0000000000..18c40bafb6
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-class@shared.tsx
@@ -0,0 +1,11 @@
+class DataStore {
+  data = new Map();
+  get(k: string) {
+    return this.data.get(k);
+  }
+  set(k: string, v: unknown) {
+    this.data.set(k, v);
+  }
+}
+const store = new DataStore();
+export { DataStore, store };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured-export.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured-export.tsx
new file mode 100644
index 0000000000..7d0f0fcae1
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured-export.tsx
@@ -0,0 +1,10 @@
+const $$splitComponentImporter = () => import('shared-destructured-export.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-destructured-export.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/config')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
+export { apiUrl, timeout } from "shared-destructured-export.tsx?tsr-shared=1";
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured-export@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured-export@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..16b288ac5f
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured-export@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,3 @@
+import { timeout } from "shared-destructured-export.tsx?tsr-shared=1";
+const SplitComponent = () => <div>Timeout: {timeout}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured-export@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured-export@loader.tsx
new file mode 100644
index 0000000000..33d4b5aa43
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured-export@loader.tsx
@@ -0,0 +1,3 @@
+import { apiUrl } from "shared-destructured-export.tsx?tsr-shared=1";
+const SplitLoader = async () => fetch(apiUrl);
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured-export@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured-export@shared.tsx
new file mode 100644
index 0000000000..f0bfd70add
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured-export@shared.tsx
@@ -0,0 +1,11 @@
+const {
+  apiUrl,
+  timeout
+} = getConfig();
+function getConfig() {
+  return {
+    apiUrl: '/api',
+    timeout: 5000
+  };
+}
+export { apiUrl, getConfig, timeout };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured.tsx
new file mode 100644
index 0000000000..8185738e9d
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-destructured.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-destructured.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/config')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..5c0182e61a
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,3 @@
+import { timeout } from "shared-destructured.tsx?tsr-shared=1";
+const SplitComponent = () => <div>Timeout: {timeout}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured@loader.tsx
new file mode 100644
index 0000000000..94b0923079
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured@loader.tsx
@@ -0,0 +1,3 @@
+import { apiUrl } from "shared-destructured.tsx?tsr-shared=1";
+const SplitLoader = async () => fetch(apiUrl);
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured@shared.tsx
new file mode 100644
index 0000000000..f0bfd70add
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured@shared.tsx
@@ -0,0 +1,11 @@
+const {
+  apiUrl,
+  timeout
+} = getConfig();
+function getConfig() {
+  return {
+    apiUrl: '/api',
+    timeout: 5000
+  };
+}
+export { apiUrl, getConfig, timeout };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-exported.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-exported.tsx
new file mode 100644
index 0000000000..ce690311b2
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-exported.tsx
@@ -0,0 +1,10 @@
+const $$splitComponentImporter = () => import('shared-exported.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-exported.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/query')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
+export { queryOptions } from "shared-exported.tsx?tsr-shared=1";
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-exported@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-exported@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..b020b5cadf
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-exported@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,3 @@
+import { queryOptions } from "shared-exported.tsx?tsr-shared=1";
+const SplitComponent = () => <div>GC: {queryOptions.gcTime}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-exported@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-exported@loader.tsx
new file mode 100644
index 0000000000..332fa35079
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-exported@loader.tsx
@@ -0,0 +1,7 @@
+import { queryOptions } from "shared-exported.tsx?tsr-shared=1";
+const SplitLoader = async () => {
+  return {
+    staleTime: queryOptions.staleTime
+  };
+};
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-exported@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-exported@shared.tsx
new file mode 100644
index 0000000000..a3f91b85bb
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-exported@shared.tsx
@@ -0,0 +1,5 @@
+const queryOptions = {
+  staleTime: 5000,
+  gcTime: 10000
+};
+export { queryOptions };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-function.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-function.tsx
new file mode 100644
index 0000000000..b5bf41235e
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-function.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-function.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-function.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/cached')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-function@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-function@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..571bd9356a
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-function@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,3 @@
+import { getCached } from "shared-function.tsx?tsr-shared=1";
+const SplitComponent = () => <div>{JSON.stringify(getCached('data'))}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-function@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-function@loader.tsx
new file mode 100644
index 0000000000..f5f72ab014
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-function@loader.tsx
@@ -0,0 +1,9 @@
+import { getCached, cache } from "shared-function.tsx?tsr-shared=1";
+function setCached(key: string, val: unknown) {
+  cache.set(key, val);
+}
+const SplitLoader = async () => {
+  setCached('data', await fetch('/api').then(r => r.json()));
+  return getCached('data');
+};
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-function@shared.tsx
new file mode 100644
index 0000000000..27d2cf03f1
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-function@shared.tsx
@@ -0,0 +1,5 @@
+const cache = new Map();
+function getCached(key: string) {
+  return cache.get(key);
+}
+export { cache, getCached };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-imported-binding.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-imported-binding.tsx
new file mode 100644
index 0000000000..d9ce6828fa
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-imported-binding.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-imported-binding.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-imported-binding.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/imported')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-imported-binding@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-imported-binding@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..0a835ae063
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-imported-binding@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,3 @@
+import { sharedUtil } from '../utils';
+const SplitComponent = () => <div>{sharedUtil('render')}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-imported-binding@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-imported-binding@loader.tsx
new file mode 100644
index 0000000000..1b27de9093
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-imported-binding@loader.tsx
@@ -0,0 +1,3 @@
+import { sharedUtil } from '../utils';
+const SplitLoader = async () => sharedUtil('load');
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-imported-binding@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-imported-binding@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-indirect-ref.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-indirect-ref.tsx
new file mode 100644
index 0000000000..f4dfce52ba
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-indirect-ref.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-indirect-ref.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-indirect-ref.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/shared-indirect')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-indirect-ref@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-indirect-ref@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..62995e7fd8
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-indirect-ref@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,7 @@
+import { state, getCount } from "shared-indirect-ref.tsx?tsr-shared=1";
+function SharedComponent() {
+  return <div>
+      {getCount()} - {state.count}
+    </div>;
+}
+export { SharedComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-indirect-ref@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-indirect-ref@loader.tsx
new file mode 100644
index 0000000000..0625ac53f8
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-indirect-ref@loader.tsx
@@ -0,0 +1,8 @@
+import { state, getCount } from "shared-indirect-ref.tsx?tsr-shared=1";
+const SplitLoader = () => {
+  state.count++;
+  return {
+    count: getCount()
+  };
+};
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-indirect-ref@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-indirect-ref@shared.tsx
new file mode 100644
index 0000000000..7e7e811ba8
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-indirect-ref@shared.tsx
@@ -0,0 +1,7 @@
+const state = {
+  count: 0
+};
+function getCount() {
+  return state.count;
+}
+export { getCount, state };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-jsx-component-ref.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-jsx-component-ref.tsx
new file mode 100644
index 0000000000..8ac24d49cf
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-jsx-component-ref.tsx
@@ -0,0 +1,10 @@
+const $$splitComponentImporter = () => import('shared-jsx-component-ref.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-jsx-component-ref.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+// @ts-nocheck
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/jsx')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-jsx-component-ref@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-jsx-component-ref@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..52ecb6d474
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-jsx-component-ref@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,5 @@
+import { shared } from "shared-jsx-component-ref.tsx?tsr-shared=1"; // @ts-nocheck
+function SharedComponent() {
+  return <div>{shared}</div>;
+}
+export { SharedComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-jsx-component-ref@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-jsx-component-ref@loader.tsx
new file mode 100644
index 0000000000..f861dda436
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-jsx-component-ref@loader.tsx
@@ -0,0 +1,3 @@
+import { shared } from "shared-jsx-component-ref.tsx?tsr-shared=1"; // @ts-nocheck
+const SplitLoader = () => shared;
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-jsx-component-ref@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-jsx-component-ref@shared.tsx
new file mode 100644
index 0000000000..d5cc2cf990
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-jsx-component-ref@shared.tsx
@@ -0,0 +1,4 @@
+// @ts-nocheck
+
+const shared = 1;
+export { shared };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-none.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-none.tsx
new file mode 100644
index 0000000000..06e81042d6
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-none.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-none.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-none.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/clean')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-none@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-none@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..701deeedeb
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-none@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,5 @@
+const ComponentHelper = () => <span>helper</span>;
+const SplitComponent = () => <div>
+      <ComponentHelper />
+    </div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-none@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-none@loader.tsx
new file mode 100644
index 0000000000..d0cfce36ee
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-none@loader.tsx
@@ -0,0 +1,3 @@
+const loaderHelper = () => fetch('/api');
+const SplitLoader = async () => loaderHelper();
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-none@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-none@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-referencing-route.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-referencing-route.tsx
new file mode 100644
index 0000000000..b62568c1fb
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-referencing-route.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-referencing-route.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-referencing-route.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/about')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-referencing-route@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-referencing-route@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..2cb2cdb68c
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-referencing-route@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,10 @@
+import { HEADER } from "shared-referencing-route.tsx?tsr-shared=1";
+function usePageTitle() {
+  return `${HEADER} - ${Route.fullPath}`;
+}
+import { Route } from "shared-referencing-route.tsx";
+const SplitComponent = () => {
+  const title = usePageTitle();
+  return <div>{title}</div>;
+};
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-referencing-route@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-referencing-route@loader.tsx
new file mode 100644
index 0000000000..baedd53bd7
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-referencing-route@loader.tsx
@@ -0,0 +1,12 @@
+import { HEADER } from "shared-referencing-route.tsx?tsr-shared=1";
+function usePageTitle() {
+  return `${HEADER} - ${Route.fullPath}`;
+}
+import { Route } from "shared-referencing-route.tsx";
+const SplitLoader = async () => {
+  const title = usePageTitle();
+  return {
+    title
+  };
+};
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-referencing-route@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-referencing-route@shared.tsx
new file mode 100644
index 0000000000..cc2d01424c
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-referencing-route@shared.tsx
@@ -0,0 +1,2 @@
+const HEADER = 'Page';
+export { HEADER };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-transitive.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-transitive.tsx
new file mode 100644
index 0000000000..869602e15b
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-transitive.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-transitive.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-transitive.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/api')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-transitive@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-transitive@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..7a3a74048e
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-transitive@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,3 @@
+import { config } from "shared-transitive.tsx?tsr-shared=1";
+const SplitComponent = () => <div>Timeout: {config.timeout}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-transitive@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-transitive@loader.tsx
new file mode 100644
index 0000000000..8472eab295
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-transitive@loader.tsx
@@ -0,0 +1,6 @@
+import { config } from "shared-transitive.tsx?tsr-shared=1";
+const fetcher = (path: string) => fetch(`${config.url}${path}`);
+const SplitLoader = async () => {
+  return fetcher('/data');
+};
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-transitive@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-transitive@shared.tsx
new file mode 100644
index 0000000000..8bec4a1d55
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-transitive@shared.tsx
@@ -0,0 +1,6 @@
+const BASE_URL = 'https://api.example.com';
+const config = {
+  url: BASE_URL,
+  timeout: 5000
+};
+export { BASE_URL, config };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-variable.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-variable.tsx
new file mode 100644
index 0000000000..42f68cce48
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-variable.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-variable.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-variable.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/todos')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-variable@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-variable@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..d149922fbc
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-variable@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,3 @@
+import { collection } from "shared-variable.tsx?tsr-shared=1";
+const SplitComponent = () => <div>{collection.name}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-variable@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-variable@loader.tsx
new file mode 100644
index 0000000000..196a8e48a4
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-variable@loader.tsx
@@ -0,0 +1,8 @@
+import { collection } from "shared-variable.tsx?tsr-shared=1";
+const SplitLoader = async () => {
+  await collection.preload();
+  return {
+    data: 'loaded'
+  };
+};
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-variable@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-variable@shared.tsx
new file mode 100644
index 0000000000..8a0560d5b9
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-variable@shared.tsx
@@ -0,0 +1,5 @@
+const collection = {
+  name: 'todos',
+  preload: async () => {}
+};
+export { collection };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-with-side-effect.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-with-side-effect.tsx
new file mode 100644
index 0000000000..943cdf189c
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-with-side-effect.tsx
@@ -0,0 +1,10 @@
+const $$splitComponentImporter = () => import('shared-with-side-effect.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-with-side-effect.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+console.log('registry created');
+export const Route = createFileRoute('/fx')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-with-side-effect@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-with-side-effect@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..d953af00fa
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-with-side-effect@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,3 @@
+import { registry } from "shared-with-side-effect.tsx?tsr-shared=1";
+const SplitComponent = () => <div>{registry.size}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-with-side-effect@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-with-side-effect@loader.tsx
new file mode 100644
index 0000000000..a5f06a0a05
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-with-side-effect@loader.tsx
@@ -0,0 +1,5 @@
+import { registry } from "shared-with-side-effect.tsx?tsr-shared=1";
+const SplitLoader = async () => {
+  registry.set('loaded', true);
+};
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-with-side-effect@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-with-side-effect@shared.tsx
new file mode 100644
index 0000000000..f26c656fdd
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-with-side-effect@shared.tsx
@@ -0,0 +1,2 @@
+const registry = new Map();
+export { registry };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/undefined-literals@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/undefined-literals@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/useStateDestructure@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/useStateDestructure@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/using@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/using@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/arrow-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/arrow-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/boolean-null-literals@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/boolean-null-literals@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/chinese@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/chinese@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/circular-reference-arrow-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/circular-reference-arrow-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/circular-reference-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/circular-reference-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/conditional-properties@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/conditional-properties@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export-multiple@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export-multiple@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export-nested@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export-nested@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-react-memo-imported-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-react-memo-imported-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-route-options-defaults@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-route-options-defaults@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructuring@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructuring@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/directive-prologue.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/directive-prologue.tsx
new file mode 100644
index 0000000000..178bec9bf7
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/directive-prologue.tsx
@@ -0,0 +1,8 @@
+'use client';
+
+const $$splitComponentImporter = () => import('directive-prologue.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/directive')({
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/directive-prologue@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/directive-prologue@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..ce7cd5e5ee
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/directive-prologue@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,6 @@
+'use client';
+
+const SplitComponent = () => {
+  return <div>directive preserved</div>;
+};
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/directive-prologue@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/directive-prologue@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/directive-prologue@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/directive-prologue@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/explicit-undefined-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/explicit-undefined-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/export-default-component-and-normal-notFound@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/export-default-component-and-normal-notFound@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/export-default-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/export-default-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/function-as-parameter@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/function-as-parameter@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/function-declaration@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/function-declaration@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/importAttribute@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/importAttribute@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/imported-default-component-destructured-loader@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/imported-default-component-destructured-loader@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/imported-default-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/imported-default-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/imported-errorComponent@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/imported-errorComponent@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/imported-notFoundComponent@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/imported-notFoundComponent@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/imported-pendingComponent@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/imported-pendingComponent@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/imported@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/imported@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/inline@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/inline@component---loader---notFoundComponent---pendingComponent.tsx
index 4b18cae17a..58ccfb2903 100644
--- a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/inline@component---loader---notFoundComponent---pendingComponent.tsx
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/inline@component---loader---notFoundComponent---pendingComponent.tsx
@@ -7,7 +7,6 @@ const Button = (props: {
   return <button>{props.children}</button>;
 };
 import { Route } from "inline.tsx";
-Route.addChildren([]);
 import { test } from "inline.tsx";
 const SplitComponent = () => {
   return <div className="p-2">
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/inline@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/inline@errorComponent.tsx
index 4a822161e1..9236af6021 100644
--- a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/inline@errorComponent.tsx
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/inline@errorComponent.tsx
@@ -1,3 +1,2 @@
 import * as React from 'react';
-import { Route } from "inline.tsx";
-Route.addChildren([]);
\ No newline at end of file
+import { Route } from "inline.tsx";
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/inline@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/inline@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/random-number@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/random-number@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/react-memo-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/react-memo-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/react-memo-imported-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/react-memo-imported-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-export-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-export-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-exports-const@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-exports-const@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-exports-destructured@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-exports-destructured@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-exports-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-exports-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-exports-loader@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-exports-loader@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-class.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-class.tsx
new file mode 100644
index 0000000000..48afc3f070
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-class.tsx
@@ -0,0 +1,18 @@
+const $$splitComponentImporter = () => import('shared-class.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-class.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+class DataStore {
+  data = new Map();
+  get(k: string) {
+    return this.data.get(k);
+  }
+  set(k: string, v: unknown) {
+    this.data.set(k, v);
+  }
+}
+export const Route = createFileRoute('/store')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-class@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-class@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..10675b99ed
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-class@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,16 @@
+class DataStore {
+  data = new Map();
+  get(k: string) {
+    return this.data.get(k);
+  }
+  set(k: string, v: unknown) {
+    this.data.set(k, v);
+  }
+}
+const store = new DataStore();
+const SplitLoader = async () => {
+  store.set('items', await fetch('/api'));
+};
+export { SplitLoader as loader };
+const SplitComponent = () => <div>{store.get('items')}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-class@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-class@errorComponent.tsx
new file mode 100644
index 0000000000..0a50638c6a
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-class@errorComponent.tsx
@@ -0,0 +1,9 @@
+class DataStore {
+  data = new Map();
+  get(k: string) {
+    return this.data.get(k);
+  }
+  set(k: string, v: unknown) {
+    this.data.set(k, v);
+  }
+}
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-class@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-class@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured-export.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured-export.tsx
new file mode 100644
index 0000000000..73f1b54389
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured-export.tsx
@@ -0,0 +1,19 @@
+const $$splitComponentImporter = () => import('shared-destructured-export.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-destructured-export.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const {
+  apiUrl,
+  timeout
+} = getConfig();
+export const Route = createFileRoute('/config')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
+function getConfig() {
+  return {
+    apiUrl: '/api',
+    timeout: 5000
+  };
+}
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured-export@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured-export@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..d48accf910
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured-export@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,5 @@
+import { apiUrl, timeout } from "shared-destructured-export.tsx";
+const SplitLoader = async () => fetch(apiUrl);
+export { SplitLoader as loader };
+const SplitComponent = () => <div>Timeout: {timeout}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured-export@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured-export@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured-export@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured-export@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured.tsx
new file mode 100644
index 0000000000..fbc4272c3e
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-destructured.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-destructured.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/config')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..e92f7dd7f8
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,14 @@
+const {
+  apiUrl,
+  timeout
+} = getConfig();
+function getConfig() {
+  return {
+    apiUrl: '/api',
+    timeout: 5000
+  };
+}
+const SplitLoader = async () => fetch(apiUrl);
+export { SplitLoader as loader };
+const SplitComponent = () => <div>Timeout: {timeout}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-exported.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-exported.tsx
new file mode 100644
index 0000000000..76a5d29dc3
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-exported.tsx
@@ -0,0 +1,13 @@
+const $$splitComponentImporter = () => import('shared-exported.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-exported.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const queryOptions = {
+  staleTime: 5000,
+  gcTime: 10000
+};
+export const Route = createFileRoute('/query')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-exported@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-exported@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..f77f81cbdb
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-exported@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,9 @@
+import { queryOptions } from "shared-exported.tsx";
+const SplitLoader = async () => {
+  return {
+    staleTime: queryOptions.staleTime
+  };
+};
+export { SplitLoader as loader };
+const SplitComponent = () => <div>GC: {queryOptions.gcTime}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-exported@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-exported@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-exported@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-exported@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-function.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-function.tsx
new file mode 100644
index 0000000000..8a921d9640
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-function.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-function.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-function.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/cached')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-function@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-function@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..cfe519f47a
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-function@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,14 @@
+const cache = new Map();
+function getCached(key: string) {
+  return cache.get(key);
+}
+function setCached(key: string, val: unknown) {
+  cache.set(key, val);
+}
+const SplitLoader = async () => {
+  setCached('data', await fetch('/api').then(r => r.json()));
+  return getCached('data');
+};
+export { SplitLoader as loader };
+const SplitComponent = () => <div>{JSON.stringify(getCached('data'))}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-function@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-function@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-imported-binding.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-imported-binding.tsx
new file mode 100644
index 0000000000..feb46cd789
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-imported-binding.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-imported-binding.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-imported-binding.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/imported')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-imported-binding@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-imported-binding@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..409e8d4023
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-imported-binding@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,5 @@
+import { sharedUtil } from '../utils';
+const SplitLoader = async () => sharedUtil('load');
+export { SplitLoader as loader };
+const SplitComponent = () => <div>{sharedUtil('render')}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-imported-binding@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-imported-binding@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-imported-binding@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-imported-binding@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-indirect-ref.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-indirect-ref.tsx
new file mode 100644
index 0000000000..4275e17e58
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-indirect-ref.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-indirect-ref.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-indirect-ref.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/shared-indirect')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-indirect-ref@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-indirect-ref@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..090f3b5c73
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-indirect-ref@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,19 @@
+const state = {
+  count: 0
+};
+function getCount() {
+  return state.count;
+}
+function SharedComponent() {
+  return <div>
+      {getCount()} - {state.count}
+    </div>;
+}
+const SplitLoader = () => {
+  state.count++;
+  return {
+    count: getCount()
+  };
+};
+export { SplitLoader as loader };
+export { SharedComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-indirect-ref@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-indirect-ref@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-indirect-ref@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-indirect-ref@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-jsx-component-ref.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-jsx-component-ref.tsx
new file mode 100644
index 0000000000..130c7ce120
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-jsx-component-ref.tsx
@@ -0,0 +1,10 @@
+const $$splitComponentImporter = () => import('shared-jsx-component-ref.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-jsx-component-ref.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+// @ts-nocheck
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/jsx')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-jsx-component-ref@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-jsx-component-ref@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..c5fd18664e
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-jsx-component-ref@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,9 @@
+// @ts-nocheck
+
+const shared = 1;
+function SharedComponent() {
+  return <div>{shared}</div>;
+}
+const SplitLoader = () => shared;
+export { SplitLoader as loader };
+export { SharedComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-jsx-component-ref@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-jsx-component-ref@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-jsx-component-ref@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-jsx-component-ref@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-none.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-none.tsx
new file mode 100644
index 0000000000..eac0f9ab0a
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-none.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-none.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-none.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/clean')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-none@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-none@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..f9f52ba6be
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-none@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,8 @@
+const loaderHelper = () => fetch('/api');
+const ComponentHelper = () => <span>helper</span>;
+const SplitLoader = async () => loaderHelper();
+export { SplitLoader as loader };
+const SplitComponent = () => <div>
+      <ComponentHelper />
+    </div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-none@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-none@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-none@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-none@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-referencing-route.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-referencing-route.tsx
new file mode 100644
index 0000000000..9aebb45a95
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-referencing-route.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-referencing-route.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-referencing-route.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/about')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-referencing-route@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-referencing-route@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..9bcd130ea8
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-referencing-route@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,17 @@
+const HEADER = 'Page';
+function usePageTitle() {
+  return `${HEADER} - ${Route.fullPath}`;
+}
+import { Route } from "shared-referencing-route.tsx";
+const SplitLoader = async () => {
+  const title = usePageTitle();
+  return {
+    title
+  };
+};
+export { SplitLoader as loader };
+const SplitComponent = () => {
+  const title = usePageTitle();
+  return <div>{title}</div>;
+};
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-referencing-route@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-referencing-route@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-referencing-route@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-referencing-route@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-transitive.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-transitive.tsx
new file mode 100644
index 0000000000..67b0631b8e
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-transitive.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-transitive.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-transitive.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/api')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-transitive@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-transitive@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..662d7fd7aa
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-transitive@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,12 @@
+const BASE_URL = 'https://api.example.com';
+const config = {
+  url: BASE_URL,
+  timeout: 5000
+};
+const fetcher = (path: string) => fetch(`${config.url}${path}`);
+const SplitLoader = async () => {
+  return fetcher('/data');
+};
+export { SplitLoader as loader };
+const SplitComponent = () => <div>Timeout: {config.timeout}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-transitive@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-transitive@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-transitive@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-transitive@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-variable.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-variable.tsx
new file mode 100644
index 0000000000..48cdad100e
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-variable.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-variable.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-variable.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/todos')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-variable@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-variable@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..daca782a6f
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-variable@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,13 @@
+const collection = {
+  name: 'todos',
+  preload: async () => {}
+};
+const SplitLoader = async () => {
+  await collection.preload();
+  return {
+    data: 'loaded'
+  };
+};
+export { SplitLoader as loader };
+const SplitComponent = () => <div>{collection.name}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-variable@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-variable@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-variable@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-variable@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-with-side-effect.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-with-side-effect.tsx
new file mode 100644
index 0000000000..c322746737
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-with-side-effect.tsx
@@ -0,0 +1,10 @@
+const $$splitComponentImporter = () => import('shared-with-side-effect.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-with-side-effect.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+console.log('registry created');
+export const Route = createFileRoute('/fx')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-with-side-effect@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-with-side-effect@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..6c77f8b857
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-with-side-effect@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,7 @@
+const registry = new Map();
+const SplitLoader = async () => {
+  registry.set('loaded', true);
+};
+export { SplitLoader as loader };
+const SplitComponent = () => <div>{registry.size}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-with-side-effect@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-with-side-effect@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-with-side-effect@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-with-side-effect@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/undefined-literals@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/undefined-literals@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/useStateDestructure@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/useStateDestructure@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/using@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/using@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/solid/1-default/arrow-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/solid/1-default/arrow-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/solid/2-components-combined-loader-separate/arrow-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/solid/2-components-combined-loader-separate/arrow-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/solid/3-all-combined-errorComponent-separate/arrow-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/solid/3-all-combined-errorComponent-separate/arrow-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/directive-prologue.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/directive-prologue.tsx
new file mode 100644
index 0000000000..59cad1d3da
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/directive-prologue.tsx
@@ -0,0 +1,9 @@
+'use client'
+
+import { createFileRoute } from '@tanstack/react-router'
+
+export const Route = createFileRoute('/directive')({
+  component: () => {
+    return <div>directive preserved</div>
+  },
+})
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/shared-class.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/shared-class.tsx
new file mode 100644
index 0000000000..87d2e15a63
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/shared-class.tsx
@@ -0,0 +1,19 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+class DataStore {
+  data = new Map()
+  get(k: string) {
+    return this.data.get(k)
+  }
+  set(k: string, v: unknown) {
+    this.data.set(k, v)
+  }
+}
+const store = new DataStore()
+
+export const Route = createFileRoute('/store')({
+  loader: async () => {
+    store.set('items', await fetch('/api'))
+  },
+  component: () => <div>{store.get('items')}</div>,
+})
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/shared-destructured-export.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/shared-destructured-export.tsx
new file mode 100644
index 0000000000..3004c667e3
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/shared-destructured-export.tsx
@@ -0,0 +1,12 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+export const { apiUrl, timeout } = getConfig()
+
+export const Route = createFileRoute('/config')({
+  loader: async () => fetch(apiUrl),
+  component: () => <div>Timeout: {timeout}</div>,
+})
+
+function getConfig() {
+  return { apiUrl: '/api', timeout: 5000 }
+}
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/shared-destructured.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/shared-destructured.tsx
new file mode 100644
index 0000000000..6f45457189
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/shared-destructured.tsx
@@ -0,0 +1,12 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+const { apiUrl, timeout } = getConfig()
+
+export const Route = createFileRoute('/config')({
+  loader: async () => fetch(apiUrl),
+  component: () => <div>Timeout: {timeout}</div>,
+})
+
+function getConfig() {
+  return { apiUrl: '/api', timeout: 5000 }
+}
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/shared-exported.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/shared-exported.tsx
new file mode 100644
index 0000000000..acfd046964
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/shared-exported.tsx
@@ -0,0 +1,10 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+export const queryOptions = { staleTime: 5000, gcTime: 10000 }
+
+export const Route = createFileRoute('/query')({
+  loader: async () => {
+    return { staleTime: queryOptions.staleTime }
+  },
+  component: () => <div>GC: {queryOptions.gcTime}</div>,
+})
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/shared-function.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/shared-function.tsx
new file mode 100644
index 0000000000..45abe16e66
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/shared-function.tsx
@@ -0,0 +1,17 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+const cache = new Map()
+function getCached(key: string) {
+  return cache.get(key)
+}
+function setCached(key: string, val: unknown) {
+  cache.set(key, val)
+}
+
+export const Route = createFileRoute('/cached')({
+  loader: async () => {
+    setCached('data', await fetch('/api').then((r) => r.json()))
+    return getCached('data')
+  },
+  component: () => <div>{JSON.stringify(getCached('data'))}</div>,
+})
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/shared-imported-binding.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/shared-imported-binding.tsx
new file mode 100644
index 0000000000..e46da7cd6a
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/shared-imported-binding.tsx
@@ -0,0 +1,7 @@
+import { createFileRoute } from '@tanstack/react-router'
+import { sharedUtil } from '../utils'
+
+export const Route = createFileRoute('/imported')({
+  loader: async () => sharedUtil('load'),
+  component: () => <div>{sharedUtil('render')}</div>,
+})
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/shared-indirect-ref.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/shared-indirect-ref.tsx
new file mode 100644
index 0000000000..f4f50318b7
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/shared-indirect-ref.tsx
@@ -0,0 +1,23 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+const state = { count: 0 }
+
+function getCount() {
+  return state.count
+}
+
+export const Route = createFileRoute('/shared-indirect')({
+  loader: () => {
+    state.count++
+    return { count: getCount() }
+  },
+  component: SharedComponent,
+})
+
+function SharedComponent() {
+  return (
+    <div>
+      {getCount()} - {state.count}
+    </div>
+  )
+}
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/shared-jsx-component-ref.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/shared-jsx-component-ref.tsx
new file mode 100644
index 0000000000..0eb8d4f166
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/shared-jsx-component-ref.tsx
@@ -0,0 +1,13 @@
+// @ts-nocheck
+import { createFileRoute } from '@tanstack/react-router'
+
+const shared = 1
+
+function SharedComponent() {
+  return <div>{shared}</div>
+}
+
+export const Route = createFileRoute('/jsx')({
+  loader: () => shared,
+  component: SharedComponent,
+})
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/shared-none.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/shared-none.tsx
new file mode 100644
index 0000000000..1b2c2c1244
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/shared-none.tsx
@@ -0,0 +1,13 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+const loaderHelper = () => fetch('/api')
+const ComponentHelper = () => <span>helper</span>
+
+export const Route = createFileRoute('/clean')({
+  loader: async () => loaderHelper(),
+  component: () => (
+    <div>
+      <ComponentHelper />
+    </div>
+  ),
+})
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/shared-referencing-route.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/shared-referencing-route.tsx
new file mode 100644
index 0000000000..5bfbd85229
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/shared-referencing-route.tsx
@@ -0,0 +1,18 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+const HEADER = 'Page'
+
+function usePageTitle() {
+  return `${HEADER} - ${Route.fullPath}`
+}
+
+export const Route = createFileRoute('/about')({
+  loader: async () => {
+    const title = usePageTitle()
+    return { title }
+  },
+  component: () => {
+    const title = usePageTitle()
+    return <div>{title}</div>
+  },
+})
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/shared-transitive.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/shared-transitive.tsx
new file mode 100644
index 0000000000..e1471305cb
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/shared-transitive.tsx
@@ -0,0 +1,12 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+const BASE_URL = 'https://api.example.com'
+const config = { url: BASE_URL, timeout: 5000 }
+const fetcher = (path: string) => fetch(`${config.url}${path}`)
+
+export const Route = createFileRoute('/api')({
+  loader: async () => {
+    return fetcher('/data')
+  },
+  component: () => <div>Timeout: {config.timeout}</div>,
+})
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/shared-variable.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/shared-variable.tsx
new file mode 100644
index 0000000000..8cd7224e02
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/shared-variable.tsx
@@ -0,0 +1,11 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+const collection = { name: 'todos', preload: async () => {} }
+
+export const Route = createFileRoute('/todos')({
+  loader: async () => {
+    await collection.preload()
+    return { data: 'loaded' }
+  },
+  component: () => <div>{collection.name}</div>,
+})
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/shared-with-side-effect.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/shared-with-side-effect.tsx
new file mode 100644
index 0000000000..b926dfe889
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/shared-with-side-effect.tsx
@@ -0,0 +1,11 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+const registry = new Map()
+console.log('registry created')
+
+export const Route = createFileRoute('/fx')({
+  loader: async () => {
+    registry.set('loaded', true)
+  },
+  component: () => <div>{registry.size}</div>,
+})
diff --git a/packages/router-plugin/tests/shared-bindings-helpers.test.ts b/packages/router-plugin/tests/shared-bindings-helpers.test.ts
new file mode 100644
index 0000000000..3198c15fb9
--- /dev/null
+++ b/packages/router-plugin/tests/shared-bindings-helpers.test.ts
@@ -0,0 +1,1040 @@
+import { describe, expect, it } from 'vitest'
+import * as t from '@babel/types'
+import { parseAst } from '@tanstack/router-utils'
+
+import {
+  addSharedSearchParamToFilename,
+  buildDeclarationMap,
+  buildDependencyGraph,
+  collectIdentifiersFromNode,
+  collectLocalBindingsFromStatement,
+  collectModuleLevelRefsFromNode,
+  computeSharedBindings,
+  expandDestructuredDeclarations,
+  expandTransitively,
+  removeBindingsDependingOnRoute,
+} from '../src/core/code-splitter/compilers'
+import { defaultCodeSplitGroupings } from '../src/core/constants'
+import type { CodeSplitGroupings } from '../src/core/constants'
+
+// ─── Test helpers ──────────────────────────────────────────
+
+function parse(code: string) {
+  return parseAst({ code })
+}
+
+function collectBindings(code: string): Set<string> {
+  const ast = parse(code)
+  const bindings = new Set<string>()
+  for (const node of ast.program.body) {
+    collectLocalBindingsFromStatement(node, bindings)
+  }
+  return bindings
+}
+
+/** Build a dep graph from code for convenience */
+function graphFromCode(code: string) {
+  const ast = parse(code)
+  const locals = new Set<string>()
+  for (const node of ast.program.body) {
+    collectLocalBindingsFromStatement(node, locals)
+  }
+  const declMap = buildDeclarationMap(ast)
+  return {
+    ast,
+    locals,
+    declMap,
+    depGraph: buildDependencyGraph(declMap, locals),
+  }
+}
+
+// ─── addSharedSearchParamToFilename ────────────────────────
+
+describe('addSharedSearchParamToFilename', () => {
+  it('should append tsr-shared=1 to bare filename', () => {
+    expect(addSharedSearchParamToFilename('src/routes/index.tsx')).toBe(
+      'src/routes/index.tsx?tsr-shared=1',
+    )
+  })
+
+  it('should strip existing query params', () => {
+    expect(
+      addSharedSearchParamToFilename(
+        'src/routes/index.tsx?tsr-split=component',
+      ),
+    ).toBe('src/routes/index.tsx?tsr-shared=1')
+  })
+})
+
+// ─── collectIdentifiersFromNode ───────────────────────────
+
+describe('collectIdentifiersFromNode', () => {
+  it('should collect from a simple identifier', () => {
+    const ast = parse('const x = foo')
+    const decl = ast.program.body[0] as t.VariableDeclaration
+    const init = decl.declarations[0]!.init!
+    expect(collectIdentifiersFromNode(init)).toEqual(new Set(['foo']))
+  })
+
+  it('should collect from a binary expression', () => {
+    const ast = parse('const x = a + b')
+    const decl = ast.program.body[0] as t.VariableDeclaration
+    const init = decl.declarations[0]!.init!
+    expect(collectIdentifiersFromNode(init)).toEqual(new Set(['a', 'b']))
+  })
+
+  it('should ignore object literal keys', () => {
+    const ast = parse('const x = { key: value }')
+    const decl = ast.program.body[0] as t.VariableDeclaration
+    const init = decl.declarations[0]!.init!
+    const ids = collectIdentifiersFromNode(init)
+    expect(ids).toContain('value')
+    expect(ids).not.toContain('key')
+  })
+
+  it('should ignore member expression properties', () => {
+    const ast = parse('const x = obj.prop + obj[dynamic]')
+    const decl = ast.program.body[0] as t.VariableDeclaration
+    const init = decl.declarations[0]!.init!
+    const ids = collectIdentifiersFromNode(init)
+    expect(ids).toContain('obj')
+    expect(ids).toContain('dynamic')
+    expect(ids).not.toContain('prop')
+  })
+
+  it('should collect from a call expression', () => {
+    const ast = parse('const x = foo(bar, baz)')
+    const decl = ast.program.body[0] as t.VariableDeclaration
+    const init = decl.declarations[0]!.init!
+    expect(collectIdentifiersFromNode(init)).toEqual(
+      new Set(['foo', 'bar', 'baz']),
+    )
+  })
+
+  it('should collect from arrow function body', () => {
+    const ast = parse('const x = () => a + b')
+    const decl = ast.program.body[0] as t.VariableDeclaration
+    const init = decl.declarations[0]!.init!
+    const ids = collectIdentifiersFromNode(init)
+    expect(ids).toContain('a')
+    expect(ids).toContain('b')
+  })
+
+  it('should collect from member expressions', () => {
+    const ast = parse('const x = obj.prop')
+    const decl = ast.program.body[0] as t.VariableDeclaration
+    const init = decl.declarations[0]!.init!
+    const ids = collectIdentifiersFromNode(init)
+    expect(ids).toContain('obj')
+    // property name is not a referenced identifier
+    expect(ids).not.toContain('prop')
+  })
+
+  it('should collect from nested structures', () => {
+    const ast = parse('const x = { key: fn(val) }')
+    const decl = ast.program.body[0] as t.VariableDeclaration
+    const init = decl.declarations[0]!.init!
+    const ids = collectIdentifiersFromNode(init)
+    expect(ids).toContain('fn')
+    expect(ids).toContain('val')
+    // object literal keys are not referenced identifiers
+    expect(ids).not.toContain('key')
+  })
+
+  it('should return empty set for a numeric literal', () => {
+    const ast = parse('const x = 42')
+    const decl = ast.program.body[0] as t.VariableDeclaration
+    const init = decl.declarations[0]!.init!
+    expect(collectIdentifiersFromNode(init).size).toBe(0)
+  })
+
+  it('should collect from function declaration body', () => {
+    const ast = parse('function foo() { return bar + baz }')
+    const fn = ast.program.body[0]!
+    const ids = collectIdentifiersFromNode(fn)
+    // function name is a binding, not a reference
+    expect(ids).not.toContain('foo')
+    expect(ids).toContain('bar')
+    expect(ids).toContain('baz')
+  })
+})
+
+// ─── collectLocalBindingsFromStatement ─────────────────────
+
+describe('collectLocalBindingsFromStatement', () => {
+  it('should collect from const declaration', () => {
+    expect(collectBindings('const x = 1')).toEqual(new Set(['x']))
+  })
+
+  it('should collect from let declaration', () => {
+    expect(collectBindings('let x = 1')).toEqual(new Set(['x']))
+  })
+
+  it('should collect from multiple declarators', () => {
+    expect(collectBindings('const x = 1, y = 2')).toEqual(new Set(['x', 'y']))
+  })
+
+  it('should collect from function declaration', () => {
+    expect(collectBindings('function foo() {}')).toEqual(new Set(['foo']))
+  })
+
+  it('should collect from class declaration', () => {
+    expect(collectBindings('class Foo {}')).toEqual(new Set(['Foo']))
+  })
+
+  it('should collect from exported variable declaration', () => {
+    expect(collectBindings('export const x = 1')).toEqual(new Set(['x']))
+  })
+
+  it('should collect from exported function declaration', () => {
+    expect(collectBindings('export function foo() {}')).toEqual(
+      new Set(['foo']),
+    )
+  })
+
+  it('should collect from exported class declaration', () => {
+    expect(collectBindings('export class Foo {}')).toEqual(new Set(['Foo']))
+  })
+
+  it('should collect from object destructuring', () => {
+    expect(collectBindings('const { a, b } = obj')).toEqual(new Set(['a', 'b']))
+  })
+
+  it('should collect from nested object destructuring', () => {
+    expect(collectBindings('const { a: { b, c } } = obj')).toEqual(
+      new Set(['b', 'c']),
+    )
+  })
+
+  it('should collect from array destructuring', () => {
+    expect(collectBindings('const [a, b] = arr')).toEqual(new Set(['a', 'b']))
+  })
+
+  it('should collect from destructuring with defaults', () => {
+    expect(collectBindings('const { a = 1, b = 2 } = obj')).toEqual(
+      new Set(['a', 'b']),
+    )
+  })
+
+  it('should collect from destructuring with rest', () => {
+    expect(collectBindings('const { a, ...rest } = obj')).toEqual(
+      new Set(['a', 'rest']),
+    )
+  })
+
+  it('should collect from exported destructuring', () => {
+    expect(collectBindings('export const { a, b } = fn()')).toEqual(
+      new Set(['a', 'b']),
+    )
+  })
+
+  it('should NOT collect from import declarations', () => {
+    expect(collectBindings("import { a } from './mod'")).toEqual(new Set())
+  })
+
+  it('should NOT collect from expression statements', () => {
+    expect(collectBindings('console.log("hello")')).toEqual(new Set())
+  })
+
+  it('should collect from renamed destructuring', () => {
+    expect(collectBindings('const { a: renamedA } = obj')).toEqual(
+      new Set(['renamedA']),
+    )
+  })
+
+  it('should collect from multiple statements', () => {
+    const code = `
+const x = 1
+function foo() {}
+class Bar {}
+`
+    expect(collectBindings(code)).toEqual(new Set(['x', 'foo', 'Bar']))
+  })
+})
+
+// ─── buildDeclarationMap ──────────────────────────────────
+
+describe('buildDeclarationMap', () => {
+  it('should map variable names to their declarator nodes', () => {
+    const ast = parse('const x = 1\nconst y = 2')
+    const map = buildDeclarationMap(ast)
+    expect(map.has('x')).toBe(true)
+    expect(map.has('y')).toBe(true)
+    expect(t.isVariableDeclarator(map.get('x'))).toBe(true)
+  })
+
+  it('should map function declarations', () => {
+    const ast = parse('function foo() {}')
+    const map = buildDeclarationMap(ast)
+    expect(map.has('foo')).toBe(true)
+    expect(t.isFunctionDeclaration(map.get('foo'))).toBe(true)
+  })
+
+  it('should map class declarations', () => {
+    const ast = parse('class Bar {}')
+    const map = buildDeclarationMap(ast)
+    expect(map.has('Bar')).toBe(true)
+    expect(t.isClassDeclaration(map.get('Bar'))).toBe(true)
+  })
+
+  it('should map exported declarations', () => {
+    const ast = parse('export const x = 1\nexport function foo() {}')
+    const map = buildDeclarationMap(ast)
+    expect(map.has('x')).toBe(true)
+    expect(map.has('foo')).toBe(true)
+  })
+
+  it('should map destructured bindings to same declarator', () => {
+    const ast = parse('const { a, b } = fn()')
+    const map = buildDeclarationMap(ast)
+    expect(map.has('a')).toBe(true)
+    expect(map.has('b')).toBe(true)
+    expect(map.get('a')).toBe(map.get('b'))
+  })
+
+  it('should not include imports', () => {
+    const ast = parse("import { x } from './mod'\nconst y = 1")
+    const map = buildDeclarationMap(ast)
+    expect(map.has('x')).toBe(false)
+    expect(map.has('y')).toBe(true)
+  })
+})
+
+// ─── buildDependencyGraph ─────────────────────────────────
+
+describe('buildDependencyGraph', () => {
+  it('should detect direct dependency', () => {
+    const { depGraph } = graphFromCode('const a = 1\nconst b = a + 1')
+    expect(depGraph.get('b')).toEqual(new Set(['a']))
+    expect(depGraph.get('a')).toEqual(new Set())
+  })
+
+  it('should not include self-references', () => {
+    const { depGraph } = graphFromCode('const a = () => a()')
+    expect(depGraph.get('a')!.has('a')).toBe(false)
+  })
+
+  it('should not include imported identifiers', () => {
+    const { depGraph } = graphFromCode(
+      "import { ext } from './mod'\nconst a = ext + 1",
+    )
+    // ext is not in locals, so not in deps
+    expect(depGraph.get('a')!.has('ext')).toBe(false)
+  })
+
+  it('should handle multiple deps', () => {
+    const { depGraph } = graphFromCode(
+      'const a = 1\nconst b = 2\nconst c = a + b',
+    )
+    expect(depGraph.get('c')).toEqual(new Set(['a', 'b']))
+  })
+
+  it('should handle function declaration deps', () => {
+    const { depGraph } = graphFromCode(
+      'const config = {}\nfunction init() { return config }',
+    )
+    expect(depGraph.get('init')).toEqual(new Set(['config']))
+  })
+
+  it('should handle chain deps (each link direct only)', () => {
+    const { depGraph } = graphFromCode('const a = 1\nconst b = a\nconst c = b')
+    expect(depGraph.get('c')).toEqual(new Set(['b']))
+    expect(depGraph.get('b')).toEqual(new Set(['a']))
+    expect(depGraph.get('a')).toEqual(new Set())
+  })
+})
+
+// ─── collectModuleLevelRefsFromNode ────────────────────────
+
+describe('collectModuleLevelRefsFromNode', () => {
+  it('should find identifier reference in expression', () => {
+    const code = 'const x = 1\nconst y = x + 1'
+    const ast = parse(code)
+    const locals = new Set(['x', 'y'])
+
+    const yDecl = ast.program.body[1] as t.VariableDeclaration
+    const valueNode = yDecl.declarations[0]!.init!
+
+    const refs = collectModuleLevelRefsFromNode(valueNode, locals)
+    expect(refs).toContain('x')
+    expect(refs).not.toContain('y')
+  })
+
+  it('should return empty set when no local bindings referenced', () => {
+    const code = "import { foo } from './mod'\nconst x = foo()"
+    const ast = parse(code)
+    const locals = new Set(['x']) // foo is imported, not local
+
+    const xDecl = ast.program.body[1] as t.VariableDeclaration
+    const valueNode = xDecl.declarations[0]!.init!
+
+    const refs = collectModuleLevelRefsFromNode(valueNode, locals)
+    expect(refs.size).toBe(0)
+  })
+
+  it('should find multiple references', () => {
+    const code = 'const a = 1\nconst b = 2\nconst c = a + b'
+    const ast = parse(code)
+    const locals = new Set(['a', 'b', 'c'])
+
+    const cDecl = ast.program.body[2] as t.VariableDeclaration
+    const valueNode = cDecl.declarations[0]!.init!
+
+    const refs = collectModuleLevelRefsFromNode(valueNode, locals)
+    expect(refs).toContain('a')
+    expect(refs).toContain('b')
+  })
+
+  it('should find refs inside function call arguments', () => {
+    const code = 'const config = {}\nconst result = process(config)'
+    const ast = parse(code)
+    const locals = new Set(['config', 'result'])
+
+    const resultDecl = ast.program.body[1] as t.VariableDeclaration
+    const valueNode = resultDecl.declarations[0]!.init!
+
+    const refs = collectModuleLevelRefsFromNode(valueNode, locals)
+    expect(refs).toContain('config')
+  })
+
+  it('should only return direct refs (not transitive)', () => {
+    const code = 'const a = 1\nconst b = a\nconst c = b'
+    const ast = parse(code)
+    const locals = new Set(['a', 'b', 'c'])
+
+    const cDecl = ast.program.body[2] as t.VariableDeclaration
+    const valueNode = cDecl.declarations[0]!.init!
+
+    const refs = collectModuleLevelRefsFromNode(valueNode, locals)
+    // Only b is directly referenced, NOT a (transitive expansion is separate)
+    expect(refs).toContain('b')
+    expect(refs).not.toContain('a')
+  })
+})
+
+// ─── expandTransitively ───────────────────────────────────
+
+describe('expandTransitively', () => {
+  it('should expand shared set with deps of shared bindings', () => {
+    const { depGraph } = graphFromCode('const dep = 1\nconst shared = dep + 1')
+    const shared = new Set(['shared'])
+
+    expandTransitively(shared, depGraph)
+    expect(shared).toContain('dep')
+  })
+
+  it('should handle multi-level transitive expansion', () => {
+    const { depGraph } = graphFromCode('const a = 1\nconst b = a\nconst c = b')
+    const shared = new Set(['c'])
+
+    expandTransitively(shared, depGraph)
+    expect(shared).toContain('b')
+    expect(shared).toContain('a')
+  })
+
+  it('should not expand bindings not in graph', () => {
+    const depGraph = new Map<string, Set<string>>()
+    depGraph.set('shared', new Set(['ext']))
+    // ext has no entry in graph
+    const shared = new Set(['shared'])
+
+    expandTransitively(shared, depGraph)
+    // ext added because it's a dep, even if it has no graph entry
+    expect(shared).toContain('ext')
+    expect(shared.size).toBe(2)
+  })
+
+  it('should not loop on circular references', () => {
+    const { depGraph } = graphFromCode(
+      'const a = () => b()\nconst b = () => a()',
+    )
+    const shared = new Set(['a'])
+
+    expandTransitively(shared, depGraph)
+    expect(shared).toContain('a')
+    expect(shared).toContain('b')
+  })
+
+  it('should leave shared untouched when binding has no deps', () => {
+    const depGraph = new Map<string, Set<string>>()
+    depGraph.set('x', new Set())
+    const shared = new Set(['x'])
+
+    expandTransitively(shared, depGraph)
+    expect(shared.size).toBe(1)
+    expect(shared).toContain('x')
+  })
+
+  it('should handle function declaration deps', () => {
+    const { depGraph } = graphFromCode(
+      'const config = {}\nfunction init() { return config }',
+    )
+    const shared = new Set(['init'])
+
+    expandTransitively(shared, depGraph)
+    expect(shared).toContain('config')
+  })
+
+  it('should handle empty graph', () => {
+    const depGraph = new Map<string, Set<string>>()
+    const shared = new Set(['x'])
+
+    expandTransitively(shared, depGraph)
+    expect(shared.size).toBe(1)
+  })
+})
+
+// ─── expandDestructuredDeclarations ───────────────────────
+
+describe('expandDestructuredDeclarations', () => {
+  it('should add all siblings when one destructured binding is shared', () => {
+    const ast = parse('const { a, b, c } = fn()')
+    const shared = new Set(['a'])
+
+    expandDestructuredDeclarations(ast, shared)
+    expect(shared).toContain('a')
+    expect(shared).toContain('b')
+    expect(shared).toContain('c')
+  })
+
+  it('should handle array destructuring', () => {
+    const ast = parse('const [x, y] = fn()')
+    const shared = new Set(['y'])
+
+    expandDestructuredDeclarations(ast, shared)
+    expect(shared).toContain('x')
+    expect(shared).toContain('y')
+  })
+
+  it('should not expand non-destructured declarations', () => {
+    const ast = parse('const a = 1\nconst b = 2')
+    const shared = new Set(['a'])
+
+    expandDestructuredDeclarations(ast, shared)
+    expect(shared).toContain('a')
+    expect(shared).not.toContain('b')
+  })
+
+  it('should handle exported destructured declarations', () => {
+    const ast = parse('export const { a, b } = fn()')
+    const shared = new Set(['b'])
+
+    expandDestructuredDeclarations(ast, shared)
+    expect(shared).toContain('a')
+    expect(shared).toContain('b')
+  })
+
+  it('should not touch declarations where no binding is shared', () => {
+    const ast = parse('const { a, b } = fn()\nconst { c, d } = other()')
+    const shared = new Set(['a'])
+
+    expandDestructuredDeclarations(ast, shared)
+    expect(shared).toContain('a')
+    expect(shared).toContain('b')
+    expect(shared).not.toContain('c')
+    expect(shared).not.toContain('d')
+  })
+
+  it('should handle nested destructuring', () => {
+    const ast = parse('const { a, b: { c } } = fn()')
+    const shared = new Set(['a'])
+
+    expandDestructuredDeclarations(ast, shared)
+    expect(shared).toContain('a')
+    expect(shared).toContain('c')
+  })
+
+  it('should handle destructuring with defaults', () => {
+    const ast = parse('const { a = 1, b = 2 } = fn()')
+    const shared = new Set(['a'])
+
+    expandDestructuredDeclarations(ast, shared)
+    expect(shared).toContain('b')
+  })
+
+  it('should handle destructuring with rest', () => {
+    const ast = parse('const { a, ...rest } = fn()')
+    const shared = new Set(['a'])
+
+    expandDestructuredDeclarations(ast, shared)
+    expect(shared).toContain('rest')
+  })
+})
+
+// ─── computeSharedBindings (integration) ──────────────────
+
+describe('computeSharedBindings', () => {
+  const defaultGroupings = defaultCodeSplitGroupings
+
+  it('should return empty set when no route options exist', () => {
+    const code = 'const x = 1'
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result.size).toBe(0)
+  })
+
+  it('should return empty set for root routes (unsplittable)', () => {
+    const code = `
+import { createRootRoute } from '@tanstack/react-router'
+const shared = 42
+export const Route = createRootRoute({
+  component: () => shared,
+  beforeLoad: () => shared,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result.size).toBe(0)
+  })
+
+  it('should detect binding shared between split and non-split properties', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const sharedValue = 42
+export const Route = createFileRoute('/')({
+  component: () => sharedValue,
+  beforeLoad: () => sharedValue,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result).toContain('sharedValue')
+  })
+
+  it('should NOT mark binding as shared if only used by split properties', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const myComponent = () => <div />
+export const Route = createFileRoute('/')({
+  component: myComponent,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result.size).toBe(0)
+  })
+
+  it('should NOT mark binding as shared if only used by non-split properties', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const validator = () => true
+export const Route = createFileRoute('/')({
+  component: () => <div />,
+  beforeLoad: validator,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result.size).toBe(0)
+  })
+
+  it('should detect shared function declaration', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+function helperFn() { return 42 }
+export const Route = createFileRoute('/')({
+  component: () => helperFn(),
+  beforeLoad: () => helperFn(),
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result).toContain('helperFn')
+  })
+
+  it('should mark shared when binding used by two different split groups', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+class Config { value = 1 }
+export const Route = createFileRoute('/')({
+  component: () => new Config(),
+  loader: () => new Config(),
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: [['component'], ['loader']],
+    })
+    // component and loader are in different split groups → Config is shared
+    expect(result).toContain('Config')
+  })
+
+  it('should detect shared class when used by split and non-split', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+class Config { value = 1 }
+export const Route = createFileRoute('/')({
+  component: () => new Config(),
+  beforeLoad: () => new Config(),
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result).toContain('Config')
+  })
+
+  it('should expand transitive deps into shared set', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const BASE = 10
+const multiplier = BASE * 2
+export const Route = createFileRoute('/')({
+  component: () => multiplier,
+  beforeLoad: () => multiplier,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result).toContain('multiplier')
+    expect(result).toContain('BASE')
+  })
+
+  it('should expand destructured declarations', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const { a, b } = getValues()
+export const Route = createFileRoute('/')({
+  component: () => a,
+  beforeLoad: () => a,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result).toContain('a')
+    expect(result).toContain('b')
+  })
+
+  it('should handle no local bindings gracefully', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+export const Route = createFileRoute('/')({
+  component: () => <div />,
+  beforeLoad: () => {},
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result.size).toBe(0)
+  })
+
+  it('should not include imported bindings as shared (bundlers dedupe them)', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+import { helper } from './utils'
+export const Route = createFileRoute('/')({
+  component: () => helper(),
+  beforeLoad: () => helper(),
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result).not.toContain('helper')
+    expect(result.size).toBe(0)
+  })
+
+  it('should handle multiple shared bindings', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const a = 1
+const b = 2
+export const Route = createFileRoute('/')({
+  component: () => a + b,
+  beforeLoad: () => a + b,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result).toContain('a')
+    expect(result).toContain('b')
+  })
+
+  it('should handle chained createFileRoute call pattern', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const data = { value: 42 }
+export const Route = createFileRoute('/')({
+  component: () => data.value,
+  validateSearch: () => data,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result).toContain('data')
+  })
+
+  it('should handle loader in default groupings (not split by default)', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const config = { key: 'value' }
+export const Route = createFileRoute('/')({
+  component: () => config.key,
+  loader: () => config,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    // In default groupings, loader is NOT split → non-split
+    // component IS split → config referenced by both → shared
+    expect(result).toContain('config')
+  })
+
+  it('should handle custom groupings where loader and component are in different split groups', () => {
+    const groupings: CodeSplitGroupings = [['component'], ['loader']]
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const config = { key: 'value' }
+export const Route = createFileRoute('/')({
+  component: () => config.key,
+  loader: () => config,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: groupings,
+    })
+    // component and loader are in different split groups → config is shared
+    expect(result).toContain('config')
+  })
+
+  it('should NOT mark shared when binding used by only one split group', () => {
+    const groupings: CodeSplitGroupings = [
+      ['loader', 'component'],
+      ['errorComponent'],
+    ]
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const config = { key: 'value' }
+export const Route = createFileRoute('/')({
+  component: () => config.key,
+  loader: () => config,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: groupings,
+    })
+    // component and loader are in the SAME split group → config only in one group → not shared
+    expect(result.size).toBe(0)
+  })
+
+  it('should handle custom groupings with non-split property referencing shared binding', () => {
+    const groupings: CodeSplitGroupings = [['component'], ['loader']]
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const config = { key: 'value' }
+export const Route = createFileRoute('/')({
+  component: () => config.key,
+  loader: () => config,
+  beforeLoad: () => config,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: groupings,
+    })
+    // config used by component (split), loader (split), beforeLoad (non-split)
+    // In both splitRefs and nonSplitRefs → shared
+    expect(result).toContain('config')
+  })
+
+  it('should handle deep transitive chain with destructuring', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const base = 10
+const { x, y } = compute(base)
+export const Route = createFileRoute('/')({
+  component: () => x,
+  beforeLoad: () => x,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    // x is shared → y must be shared (destructured together)
+    // base is a transitive dep of {x, y} declaration → also shared
+    expect(result).toContain('x')
+    expect(result).toContain('y')
+    expect(result).toContain('base')
+  })
+
+  it('should NOT include bindings that transitively depend on Route', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const HEADER = 'Page'
+function usePageTitle() { return HEADER + ' - ' + Route.fullPath }
+export const Route = createFileRoute('/about')({
+  loader: () => usePageTitle(),
+  component: () => usePageTitle(),
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    // usePageTitle references Route → cannot be shared
+    expect(result).not.toContain('usePageTitle')
+    // HEADER does NOT reference Route → still safe to share
+    expect(result).toContain('HEADER')
+    // Route must never be shared
+    expect(result).not.toContain('Route')
+  })
+
+  it('should remove entire transitive chain if it reaches Route', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const routeInfo = { path: '' }
+function initRouteInfo() { routeInfo.path = Route.fullPath }
+function getTitle() { initRouteInfo(); return routeInfo.path }
+export const Route = createFileRoute('/test')({
+  loader: () => getTitle(),
+  component: () => getTitle(),
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    // getTitle → initRouteInfo → Route: entire chain cannot be shared
+    expect(result).not.toContain('getTitle')
+    expect(result).not.toContain('initRouteInfo')
+    expect(result).not.toContain('Route')
+    // routeInfo doesn't reference Route directly, but initRouteInfo does
+    // routeInfo itself may or may not be shared depending on its own deps
+  })
+
+  it('should keep bindings that do NOT depend on Route alongside ones that do', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const safeConfig = { timeout: 5000 }
+function unsafeHelper() { return Route.fullPath }
+export const Route = createFileRoute('/mixed')({
+  loader: () => ({ config: safeConfig, path: unsafeHelper() }),
+  component: () => <div>{safeConfig.timeout} {unsafeHelper()}</div>,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result).toContain('safeConfig')
+    expect(result).not.toContain('unsafeHelper')
+    expect(result).not.toContain('Route')
+  })
+})
+
+// ─── removeBindingsDependingOnRoute ───────────────────────
+
+describe('removeBindingsDependingOnRoute', () => {
+  it('should remove a binding that directly depends on Route', () => {
+    const depGraph = new Map<string, Set<string>>()
+    depGraph.set('helper', new Set(['Route']))
+    depGraph.set('Route', new Set())
+    const shared = new Set(['helper'])
+
+    removeBindingsDependingOnRoute(shared, depGraph)
+    expect(shared).not.toContain('helper')
+  })
+
+  it('should remove a binding that transitively depends on Route', () => {
+    const depGraph = new Map<string, Set<string>>()
+    depGraph.set('a', new Set(['b']))
+    depGraph.set('b', new Set(['Route']))
+    depGraph.set('Route', new Set())
+    const shared = new Set(['a'])
+
+    removeBindingsDependingOnRoute(shared, depGraph)
+    expect(shared).not.toContain('a')
+  })
+
+  it('should keep a binding that does NOT depend on Route', () => {
+    const depGraph = new Map<string, Set<string>>()
+    depGraph.set('safe', new Set(['dep']))
+    depGraph.set('dep', new Set())
+    depGraph.set('Route', new Set())
+    const shared = new Set(['safe'])
+
+    removeBindingsDependingOnRoute(shared, depGraph)
+    expect(shared).toContain('safe')
+  })
+
+  it('should handle mixed: remove Route-dependent, keep safe bindings', () => {
+    const depGraph = new Map<string, Set<string>>()
+    depGraph.set('safe', new Set(['dep']))
+    depGraph.set('dep', new Set())
+    depGraph.set('unsafe', new Set(['Route']))
+    depGraph.set('Route', new Set())
+    const shared = new Set(['safe', 'unsafe'])
+
+    removeBindingsDependingOnRoute(shared, depGraph)
+    expect(shared).toContain('safe')
+    expect(shared).not.toContain('unsafe')
+  })
+
+  it('should handle empty shared set', () => {
+    const depGraph = new Map<string, Set<string>>()
+    const shared = new Set<string>()
+
+    removeBindingsDependingOnRoute(shared, depGraph)
+    expect(shared.size).toBe(0)
+  })
+
+  it('should handle binding with no graph entry', () => {
+    const depGraph = new Map<string, Set<string>>()
+    const shared = new Set(['orphan'])
+
+    removeBindingsDependingOnRoute(shared, depGraph)
+    // No deps found → does not depend on Route → keep
+    expect(shared).toContain('orphan')
+  })
+
+  it('should handle circular deps that do NOT reach Route', () => {
+    const depGraph = new Map<string, Set<string>>()
+    depGraph.set('a', new Set(['b']))
+    depGraph.set('b', new Set(['a']))
+    depGraph.set('Route', new Set())
+    const shared = new Set(['a'])
+
+    removeBindingsDependingOnRoute(shared, depGraph)
+    expect(shared).toContain('a')
+  })
+
+  it('should handle circular deps that DO reach Route', () => {
+    const depGraph = new Map<string, Set<string>>()
+    depGraph.set('a', new Set(['b']))
+    depGraph.set('b', new Set(['a', 'Route']))
+    depGraph.set('Route', new Set())
+    const shared = new Set(['a'])
+
+    removeBindingsDependingOnRoute(shared, depGraph)
+    expect(shared).not.toContain('a')
+  })
+})
