@octanejs/tanstack-start 0.2.8 → 0.2.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/README.md +20 -0
  2. package/package.json +8 -5
  3. package/src/compiled/StartClient.tsrx +18 -0
  4. package/src/compiled/StartServer.tsrx +12 -0
  5. package/src/compiled/client.ts +2 -0
  6. package/src/compiled/default-client.js +12 -0
  7. package/src/compiled/default-server.js +9 -0
  8. package/src/compiled/server.ts +15 -0
  9. package/src/default-entry-paths.d.ts +2 -0
  10. package/src/default-entry-paths.js +6 -0
  11. package/src/internal/router-generator/config.d.ts +2 -0
  12. package/src/internal/router-generator/config.js +1 -0
  13. package/src/internal/router-generator/generator.js +1 -0
  14. package/src/internal/router-generator/template.js +9 -5
  15. package/src/internal/router-generator/transform/transform.js +19 -1
  16. package/src/internal/router-generator/transform/types.d.ts +1 -0
  17. package/src/internal/router-plugin/core/code-splitter/compilers.js +4 -1
  18. package/src/internal/router-plugin/core/code-splitter/plugins.d.ts +1 -0
  19. package/src/internal/router-plugin/core/config.d.ts +1 -0
  20. package/src/internal/router-plugin/core/router-code-splitter-plugin.js +1 -0
  21. package/src/internal/start-plugin-core/config-context.d.ts +1 -0
  22. package/src/internal/start-plugin-core/config-context.js +1 -1
  23. package/src/internal/start-plugin-core/rsbuild/schema.d.ts +1 -0
  24. package/src/internal/start-plugin-core/rsbuild/start-router-plugin.js +11 -4
  25. package/src/internal/start-plugin-core/schema.d.ts +1 -0
  26. package/src/internal/start-plugin-core/schema.js +1 -0
  27. package/src/internal/start-plugin-core/types.d.ts +1 -0
  28. package/src/internal/start-plugin-core/vite/schema.d.ts +1 -0
  29. package/src/plugin-rsbuild.d.ts +2 -0
  30. package/src/plugin-rsbuild.js +7 -3
  31. package/src/plugin-vite.d.ts +2 -0
  32. package/src/plugin-vite.js +7 -3
package/README.md CHANGED
@@ -50,11 +50,31 @@ import { createServerFn } from '@octanejs/tanstack-start';
50
50
  import { createFileRoute } from '@octanejs/tanstack-router';
51
51
  ```
52
52
 
53
+ ## Compiled Router integration
54
+
55
+ Use `tanstackStart({ compiled: true })` in either build plugin for routes authored
56
+ as compiled Octane template bodies. This selects matching default Start entries,
57
+ route scaffolds, generated route-tree imports, and lazy route imports. Existing
58
+ custom `client.entry` and `server.entry` options retain precedence.
59
+
60
+ Import routing APIs from `@octanejs/tanstack-router/compiled` throughout that
61
+ route tree. A custom client entry uses `StartClient` and `hydrateStart` from
62
+ `@octanejs/tanstack-start/compiled/client`; a custom server uses `StartServer`,
63
+ `defaultStreamHandler`, or `defaultRenderHandler` from
64
+ `@octanejs/tanstack-start/compiled/server`. The package-root server-function APIs
65
+ remain unchanged. Do not mix the ordinary and compiled Router contexts.
66
+
67
+ The compiled Start components retain the existing document hydration owner and
68
+ ready acknowledgement. The option selects the compiled rendering boundary; it
69
+ does not declare the entire Router or Start package Strong-compliant.
70
+
53
71
  ## Public entries
54
72
 
55
73
  - `@octanejs/tanstack-start`
56
74
  - `@octanejs/tanstack-start/client`
57
75
  - `@octanejs/tanstack-start/server`
76
+ - `@octanejs/tanstack-start/compiled/client`
77
+ - `@octanejs/tanstack-start/compiled/server`
58
78
  - `@octanejs/tanstack-start/plugin/vite`
59
79
  - `@octanejs/tanstack-start/plugin/rsbuild`
60
80
  - RPC and environment-marker entries used by the Start compiler
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@octanejs/tanstack-start",
3
- "version": "0.2.8",
3
+ "version": "0.2.10",
4
4
  "description": "TanStack Start for Octane, including file-route generation, server functions, SSR streaming, hydration, and Vite or Rsbuild integration.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -107,10 +107,13 @@
107
107
  "import": "./src/server-entry.js",
108
108
  "default": "./src/server-entry.js"
109
109
  },
110
- "./package.json": "./package.json"
110
+ "./package.json": "./package.json",
111
+ "./compiled/client": "./src/compiled/client.ts",
112
+ "./compiled/server": "./src/compiled/server.ts"
111
113
  },
112
114
  "sideEffects": [
113
- "./src/default-entry/client.js"
115
+ "./src/default-entry/client.js",
116
+ "./src/compiled/default-client.js"
114
117
  ],
115
118
  "dependencies": {
116
119
  "@babel/code-frame": "7.27.1",
@@ -118,7 +121,7 @@
118
121
  "@babel/template": "^7.27.2",
119
122
  "@babel/types": "^7.28.5",
120
123
  "@octanejs/rspack-plugin": "0.2.4",
121
- "@octanejs/tanstack-router": "0.2.7",
124
+ "@octanejs/tanstack-router": "0.2.9",
122
125
  "@tanstack/router-core": "1.171.34",
123
126
  "@tanstack/router-utils": "1.162.2",
124
127
  "@tanstack/start-client-core": "1.170.34",
@@ -158,7 +161,7 @@
158
161
  "devDependencies": {
159
162
  "@rsbuild/core": "^2.1.6",
160
163
  "@types/node": "^24.13.3",
161
- "octane": "0.13.2",
164
+ "octane": "0.13.7",
162
165
  "vite": "^8.1.5",
163
166
  "vitest": "^4.1.10"
164
167
  },
@@ -0,0 +1,18 @@
1
+ 'use strong';
2
+
3
+ import { HYDRATION_RANGE_BOUNDARY, useEffect } from 'octane';
4
+ import { RouterProvider } from '@octanejs/tanstack-router/compiled';
5
+ import type { AnyRouter } from '@tanstack/router-core';
6
+
7
+ export interface StartClientProps {
8
+ router: AnyRouter;
9
+ }
10
+
11
+ export function StartClient({ router }: StartClientProps) @{
12
+ useEffect(() => {
13
+ window.$_TSR?.h();
14
+ });
15
+ <RouterProvider router={router} />
16
+ }
17
+
18
+ StartClient[HYDRATION_RANGE_BOUNDARY] = 'passthrough';
@@ -0,0 +1,12 @@
1
+ 'use strong';
2
+
3
+ import { RouterProvider } from '@octanejs/tanstack-router/compiled';
4
+ import type { AnyRouter } from '@tanstack/router-core';
5
+
6
+ export interface StartServerProps {
7
+ router: AnyRouter;
8
+ }
9
+
10
+ export function StartServer({ router }: StartServerProps) @{
11
+ <RouterProvider router={router} />
12
+ }
@@ -0,0 +1,2 @@
1
+ export { StartClient, type StartClientProps } from './StartClient.tsrx';
2
+ export { hydrateStart } from '../runtime/client/hydrateStart.js';
@@ -0,0 +1,12 @@
1
+ import { hydrateRoot, initializeHydrationEventCapture } from 'octane';
2
+ import { StartClient, hydrateStart } from './client.ts';
3
+
4
+ initializeHydrationEventCapture();
5
+
6
+ hydrateStart().then((router) => {
7
+ const container = document.getElementById('__app');
8
+ if (!container) {
9
+ throw new Error('TanStack Start could not find the Octane hydration root.');
10
+ }
11
+ hydrateRoot(container, StartClient, { router });
12
+ });
@@ -0,0 +1,9 @@
1
+ import { createStartHandler, defaultStreamHandler } from './server.ts';
2
+
3
+ const handler = createStartHandler(defaultStreamHandler);
4
+
5
+ export default {
6
+ async fetch(...args) {
7
+ return await handler(...args);
8
+ },
9
+ };
@@ -0,0 +1,15 @@
1
+ import { defineHandlerCallback } from '@tanstack/start-server-core';
2
+ import { renderRouterToString, renderRouterToStream } from '@octanejs/tanstack-router/ssr/server';
3
+ import { StartServer } from './StartServer.tsrx';
4
+
5
+ export { StartServer, type StartServerProps } from './StartServer.tsrx';
6
+ export * from '@tanstack/start-server-core';
7
+
8
+ export const defaultRenderHandler = defineHandlerCallback(({ router, responseHeaders }) =>
9
+ renderRouterToString({ router, responseHeaders, App: StartServer }),
10
+ );
11
+
12
+ export const defaultStreamHandler = defineHandlerCallback(
13
+ async ({ request, router, responseHeaders }) =>
14
+ await renderRouterToStream({ request, router, responseHeaders, App: StartServer }),
15
+ );
@@ -3,3 +3,5 @@ export declare const octaneStartDefaultEntryPaths: {
3
3
  server: string;
4
4
  start: string;
5
5
  };
6
+
7
+ export declare const octaneStartCompiledEntryPaths: typeof octaneStartDefaultEntryPaths;
@@ -9,3 +9,9 @@ export const octaneStartDefaultEntryPaths = {
9
9
  server: path.resolve(defaultEntryDirectory, 'server.js'),
10
10
  start: path.resolve(defaultEntryDirectory, 'start.js'),
11
11
  };
12
+
13
+ export const octaneStartCompiledEntryPaths = {
14
+ client: path.resolve(sourceDirectory, 'compiled/default-client.js'),
15
+ server: path.resolve(sourceDirectory, 'compiled/default-server.js'),
16
+ start: octaneStartDefaultEntryPaths.start,
17
+ };
@@ -25,6 +25,7 @@ export type TokenMatcher = z.infer<typeof tokenMatcherSchema>;
25
25
  export declare const routerFrameworks: readonly ['react', 'solid', 'vue', 'octane'];
26
26
  export declare const baseConfigSchema: z.ZodObject<
27
27
  {
28
+ compiled: z.ZodOptional<z.ZodBoolean>;
28
29
  target: z.ZodDefault<
29
30
  z.ZodOptional<
30
31
  z.ZodEnum<{
@@ -119,6 +120,7 @@ export declare const baseConfigSchema: z.ZodObject<
119
120
  export type BaseConfig = z.infer<typeof baseConfigSchema>;
120
121
  export declare const configSchema: z.ZodObject<
121
122
  {
123
+ compiled: z.ZodOptional<z.ZodBoolean>;
122
124
  target: z.ZodDefault<
123
125
  z.ZodOptional<
124
126
  z.ZodEnum<{
@@ -10,6 +10,7 @@ var tokenJsonRegexSchema = z.object({
10
10
  var tokenMatcherSchema = z.union([z.string(), z.instanceof(RegExp), tokenJsonRegexSchema]);
11
11
  var baseConfigSchema = z.object({
12
12
  target: z.enum(['react', 'solid', 'vue', 'octane']).optional().default('react'),
13
+ compiled: z.boolean().optional(),
13
14
  virtualRouteConfig: virtualRootRouteSchema.or(z.string()).optional(),
14
15
  routeFilePrefix: z.string().optional(),
15
16
  routeFileIgnorePrefix: z.string().optional().default('-'),
@@ -755,6 +755,7 @@ ${acc.routeTree.map((child) => `${child.variableName}Route: typeof ${getResolved
755
755
  filename: node.fullPath,
756
756
  ctx: {
757
757
  target: this.config.target,
758
+ compiled: this.config.compiled,
758
759
  routeId: escapedRoutePath,
759
760
  lazy: node._fsRouteType === 'lazy',
760
761
  },
@@ -163,9 +163,12 @@ function getTargetTemplate(config) {
163
163
  },
164
164
  },
165
165
  };
166
- case 'octane':
166
+ case 'octane': {
167
+ const routerPackage = config.compiled
168
+ ? `${OCTANE_ROUTER_PACKAGE}/compiled`
169
+ : OCTANE_ROUTER_PACKAGE;
167
170
  return {
168
- fullPkg: OCTANE_ROUTER_PACKAGE,
171
+ fullPkg: routerPackage,
169
172
  subPkg: 'octane-router',
170
173
  rootRoute: {
171
174
  template: () =>
@@ -176,7 +179,7 @@ function getTargetTemplate(config) {
176
179
  'function RootComponent() @{\n <div>Hello "%%tsrPath%%"!<Outlet /></div>\n}\n',
177
180
  ].join(''),
178
181
  imports: {
179
- tsrImports: () => `import { Outlet, createRootRoute } from '${OCTANE_ROUTER_PACKAGE}';`,
182
+ tsrImports: () => `import { Outlet, createRootRoute } from '${routerPackage}';`,
180
183
  tsrExportStart: () => 'export const Route = createRootRoute(',
181
184
  tsrExportEnd: () => ');',
182
185
  },
@@ -190,7 +193,7 @@ function getTargetTemplate(config) {
190
193
  'function RouteComponent() @{\n <div>Hello "%%tsrPath%%"!</div>\n}\n',
191
194
  ].join(''),
192
195
  imports: {
193
- tsrImports: () => `import { createFileRoute } from '${OCTANE_ROUTER_PACKAGE}';`,
196
+ tsrImports: () => `import { createFileRoute } from '${routerPackage}';`,
194
197
  tsrExportStart: (routePath) =>
195
198
  `export const Route = createFileRoute(${serializeRoutePath(routePath)})(`,
196
199
  tsrExportEnd: () => ');',
@@ -205,13 +208,14 @@ function getTargetTemplate(config) {
205
208
  'function RouteComponent() @{\n <div>Hello "%%tsrPath%%"!</div>\n}\n',
206
209
  ].join(''),
207
210
  imports: {
208
- tsrImports: () => `import { createLazyFileRoute } from '${OCTANE_ROUTER_PACKAGE}';`,
211
+ tsrImports: () => `import { createLazyFileRoute } from '${routerPackage}';`,
209
212
  tsrExportStart: (routePath) =>
210
213
  `export const Route = createLazyFileRoute(${serializeRoutePath(routePath)})(`,
211
214
  tsrExportEnd: () => ');',
212
215
  },
213
216
  },
214
217
  };
218
+ }
215
219
  default:
216
220
  throw new Error(`router-generator: Unknown target type: ${target}`);
217
221
  }
@@ -60,7 +60,25 @@ function transform({ ctx, source, parseSource, filename, node }) {
60
60
  const expectedCallee = getExpectedRouteConstructor(ctx.lazy);
61
61
  const expectedRouteId = `${routeIdQuote}${ctx.routeId}${routeIdQuote}`;
62
62
  const currentRouteId = source.slice(routeCall.routeIdArg.start, routeCall.routeIdArg.end);
63
- const targetModule = getRouterPackage(ctx.target);
63
+ const targetModule =
64
+ getRouterPackage(ctx.target) + (ctx.target === 'octane' && ctx.compiled ? '/compiled' : '');
65
+ if (ctx.target === 'octane') {
66
+ const otherModule = getRouterPackage(ctx.target) + (ctx.compiled ? '' : '/compiled');
67
+ const mixedImport = ast.program.body.some(
68
+ (statement) =>
69
+ t.isImportDeclaration(statement) &&
70
+ statement.source.value === otherModule &&
71
+ statement.importKind !== 'type' &&
72
+ statement.specifiers.some((specifier) => specifier.importKind !== 'type'),
73
+ );
74
+ if (mixedImport)
75
+ return {
76
+ result: 'error',
77
+ error: new Error(
78
+ `Route ${filename ?? ctx.routeId} imports ${otherModule}, but this build uses ${targetModule}. Use the matching Router entry throughout the route tree and set tanstackStart({ compiled: ${Boolean(ctx.compiled)} }) consistently.`,
79
+ ),
80
+ };
81
+ }
64
82
  const imports = parseTargetImports(ast.program.body, source, targetModule);
65
83
  const s = new MagicString(source);
66
84
  let modified = false;
@@ -29,6 +29,7 @@ export type TransformResult =
29
29
  };
30
30
  export interface TransformContext {
31
31
  target: Config['target'];
32
+ compiled?: boolean;
32
33
  routeId: string;
33
34
  lazy: boolean;
34
35
  }
@@ -253,7 +253,10 @@ function compileCodeSplitReferenceRoute(opts) {
253
253
  return opts.codeSplitGroupings.findIndex((group) => group.includes(str));
254
254
  }
255
255
  const frameworkOptions = getFrameworkOptions(opts.targetFramework);
256
- const PACKAGE = frameworkOptions.package;
256
+ const PACKAGE =
257
+ opts.targetFramework === 'octane' && opts.compiled
258
+ ? `${frameworkOptions.package}/compiled`
259
+ : frameworkOptions.package;
257
260
  const LAZY_ROUTE_COMPONENT_IDENT = frameworkOptions.idents.lazyRouteComponent;
258
261
  const LAZY_FN_IDENT = frameworkOptions.idents.lazyFn;
259
262
  const stableRouteOptionKeys = [
@@ -7,6 +7,7 @@ export type CompileCodeSplitReferenceRouteOptions = {
7
7
  codeSplitGroupings: CodeSplitGroupings;
8
8
  deleteNodes?: Set<DeletableNodes>;
9
9
  targetFramework: Config['target'];
10
+ compiled?: boolean;
10
11
  filename: string;
11
12
  id: string;
12
13
  addHmr?: boolean;
@@ -55,6 +55,7 @@ type FileRouteKeys = keyof (Parameters<CreateFileRoute<any, any, any, any, any>>
55
55
  export type DeletableNodes = FileRouteKeys | (string & {});
56
56
  export declare const configSchema: z.ZodObject<
57
57
  {
58
+ compiled: z.ZodOptional<z.ZodBoolean>;
58
59
  target: z.ZodDefault<
59
60
  z.ZodOptional<
60
61
  z.ZodEnum<{
@@ -83,6 +83,7 @@ function createRouterCodeSplitterPlugin(options = {}, routerPluginContext) {
83
83
  code,
84
84
  codeSplitGroupings: splitGroupings,
85
85
  targetFramework: userConfig.target,
86
+ compiled: userConfig.compiled,
86
87
  filename: id,
87
88
  id,
88
89
  deleteNodes: userConfig.codeSplittingOptions?.deleteNodes
@@ -13,6 +13,7 @@ export declare function createStartConfigContext<TInputConfig>(opts: {
13
13
  opts: TInputConfig | undefined,
14
14
  core: {
15
15
  framework: TanStackStartCoreOptions['framework'];
16
+ compiled?: boolean;
16
17
  },
17
18
  root: string,
18
19
  ) => TanStackStartOutputConfig;
@@ -33,7 +33,7 @@ function createStartConfigContext(opts) {
33
33
  if (!startConfig)
34
34
  startConfig = opts.parseConfig(
35
35
  opts.startPluginOpts,
36
- { framework: opts.corePluginOpts.framework },
36
+ { framework: opts.corePluginOpts.framework, compiled: opts.corePluginOpts.compiled },
37
37
  requireRoot(),
38
38
  );
39
39
  return startConfig;
@@ -1741,6 +1741,7 @@ export declare function parseStartConfig(
1741
1741
  opts: z.input<typeof tanstackStartRsbuildOptionsSchema>,
1742
1742
  corePluginOpts: {
1743
1743
  framework: CompileStartFrameworkOptions;
1744
+ compiled?: boolean;
1744
1745
  },
1745
1746
  root: string,
1746
1747
  ): {
@@ -1,3 +1,4 @@
1
+ import { composeGeneratorPlugins } from '../start-router-plugin/generator-plugins/compose-generator-plugins.js';
1
2
  import { routesManifestPlugin } from '../start-router-plugin/generator-plugins/routes-manifest-plugin.js';
2
3
  import { prerenderRoutesPlugin } from '../start-router-plugin/generator-plugins/prerender-routes-plugin.js';
3
4
  import { buildRouteTreeFileFooterFromConfig } from '../start-router-plugin/route-tree-footer.js';
@@ -35,10 +36,16 @@ function registerRouterPlugins(api, opts) {
35
36
  corePluginOpts: opts.corePluginOpts,
36
37
  });
37
38
  },
38
- plugins: [
39
- routesManifestPlugin(),
40
- ...(opts.startPluginOpts.prerender?.enabled === true ? [prerenderRoutesPlugin()] : []),
41
- ],
39
+ plugins: composeGeneratorPlugins({
40
+ frameworkPlugins: opts.corePluginOpts.routerGeneratorPlugins,
41
+ userPlugins: routerConfig.plugins,
42
+ builtInPlugins: [
43
+ routesManifestPlugin(),
44
+ ...(opts.startPluginOpts.prerender?.enabled === true
45
+ ? [prerenderRoutesPlugin()]
46
+ : []),
47
+ ],
48
+ }),
42
49
  },
43
50
  routerPluginContext,
44
51
  );
@@ -118,6 +118,7 @@ export declare function parseStartConfig(
118
118
  opts: z.input<typeof tanstackStartOptionsSchema>,
119
119
  corePluginOpts: {
120
120
  framework: CompileStartFrameworkOptions;
121
+ compiled?: boolean;
121
122
  },
122
123
  root: string,
123
124
  ): {
@@ -68,6 +68,7 @@ function parseStartConfig(opts, corePluginOpts, root) {
68
68
  {
69
69
  ...options.router,
70
70
  target: corePluginOpts.framework,
71
+ compiled: corePluginOpts.compiled,
71
72
  routesDirectory,
72
73
  generatedRouteTree,
73
74
  },
@@ -107,6 +107,7 @@ export interface NormalizedClientBuild {
107
107
  }
108
108
  export interface TanStackStartCoreOptions {
109
109
  framework: CompileStartFrameworkOptions;
110
+ compiled?: boolean;
110
111
  defaultEntryPaths: {
111
112
  client: string;
112
113
  server: string;
@@ -1720,6 +1720,7 @@ export declare function parseStartConfig(
1720
1720
  opts: z.input<typeof tanstackStartViteOptionsSchema>,
1721
1721
  corePluginOpts: {
1722
1722
  framework: CompileStartFrameworkOptions;
1723
+ compiled?: boolean;
1723
1724
  },
1724
1725
  root: string,
1725
1726
  ): {
@@ -17,6 +17,8 @@ export type TanStackOctaneStartRsbuildInputConfig = Omit<
17
17
  TanStackStartRsbuildInputConfig,
18
18
  'octane'
19
19
  > & {
20
+ /** Use compiled route bodies and the compiled Router document boundary. */
21
+ compiled?: boolean;
20
22
  octane?: OctaneCompilerOptions;
21
23
  };
22
24
 
@@ -5,7 +5,10 @@ import {
5
5
  } from '#tanstack-start/plugin-core/rsbuild';
6
6
  import { OctaneRspackPlugin } from '@octanejs/rspack-plugin';
7
7
  import { octaneRouteGeneratorPlugin } from '@octanejs/tanstack-router/generator-plugin';
8
- import { octaneStartDefaultEntryPaths } from './default-entry-paths.js';
8
+ import {
9
+ octaneStartDefaultEntryPaths,
10
+ octaneStartCompiledEntryPaths,
11
+ } from './default-entry-paths.js';
9
12
  import { validateOctaneCompilerOptions } from './validate-options.js';
10
13
 
11
14
  const clientOnlyStripLoaderPath = fileURLToPath(
@@ -13,13 +16,14 @@ const clientOnlyStripLoaderPath = fileURLToPath(
13
16
  );
14
17
 
15
18
  export function tanstackStart(options) {
16
- const { octane: octaneOptions, ...startOptions } = options ?? {};
19
+ const { octane: octaneOptions, compiled = false, ...startOptions } = options ?? {};
17
20
  validateOctaneCompilerOptions(octaneOptions);
18
21
 
19
22
  const corePlugin = tanStackStartRsbuild(
20
23
  {
21
24
  framework: 'octane',
22
- defaultEntryPaths: octaneStartDefaultEntryPaths,
25
+ compiled,
26
+ defaultEntryPaths: compiled ? octaneStartCompiledEntryPaths : octaneStartDefaultEntryPaths,
23
27
  providerEnvironmentName: RSBUILD_ENVIRONMENT_NAMES.server,
24
28
  ssrIsProvider: true,
25
29
  routerGeneratorPlugins: [octaneRouteGeneratorPlugin()],
@@ -23,6 +23,8 @@ export type OctaneCompilerOptions = Omit<OctaneVitePluginOptions, 'ssr'> & {
23
23
  };
24
24
 
25
25
  export type TanStackOctaneStartViteInputConfig = TanStackStartViteInputConfig & {
26
+ /** Use compiled route bodies and the compiled Router document boundary. */
27
+ compiled?: boolean;
26
28
  octane?: OctaneCompilerOptions;
27
29
  };
28
30
 
@@ -2,7 +2,10 @@ import { START_ENVIRONMENT_NAMES, tanStackStartVite } from '#tanstack-start/plug
2
2
  import { octaneRouteGeneratorPlugin } from '@octanejs/tanstack-router/generator-plugin';
3
3
  import { octane } from 'octane/compiler/vite';
4
4
  import { octaneClientOnlyServerStrip } from './client-only-server-strip.js';
5
- import { octaneStartDefaultEntryPaths } from './default-entry-paths.js';
5
+ import {
6
+ octaneStartDefaultEntryPaths,
7
+ octaneStartCompiledEntryPaths,
8
+ } from './default-entry-paths.js';
6
9
  import { validateOctaneCompilerOptions } from './validate-options.js';
7
10
 
8
11
  // The Start runtime chain must be source-served. Its compiler removes
@@ -28,7 +31,7 @@ const WORKSPACE_SOURCE_INCLUDES = [
28
31
  ];
29
32
 
30
33
  export function tanstackStart(options) {
31
- const { octane: octaneOptions, ...startOptions } = options ?? {};
34
+ const { octane: octaneOptions, compiled = false, ...startOptions } = options ?? {};
32
35
  validateOctaneCompilerOptions(octaneOptions);
33
36
 
34
37
  // `devtools: true` is Start's shorthand for the compiler's command-aware
@@ -47,7 +50,8 @@ export function tanstackStart(options) {
47
50
 
48
51
  const corePluginOptions = {
49
52
  framework: 'octane',
50
- defaultEntryPaths: octaneStartDefaultEntryPaths,
53
+ compiled,
54
+ defaultEntryPaths: compiled ? octaneStartCompiledEntryPaths : octaneStartDefaultEntryPaths,
51
55
  providerEnvironmentName: START_ENVIRONMENT_NAMES.server,
52
56
  ssrIsProvider: true,
53
57
  ssrResolverStrategy: { type: 'default' },