router icon indicating copy to clipboard operation
router copied to clipboard

Fails to build in bun-only environment when using `virtualRouteConfig`

Open willhoney7 opened this issue 1 month ago โ€ข 4 comments

Which project does this relate to?

Router

Describe the bug

// vite.config.ts
 tanstackStart({
    router: {
        virtualRouteConfig: 'src/routes.ts',
    },
}),

When using virtualRouteConfig with tanstack/start, loadConfigFile uses tsx behind the scenes to load the config file. The problem is that tsx is node specific and doesn't work with bun.

Image

The hacky solution is to make sure your environment also has node installed. (So I've updated our Dockerfile to install node before running vite build, but then it continues to use bun to serve the server).

I am unsure what the full solution should be... change how the virtualRouteConfig gets loaded? add a "bun" flag?

Your Example Website or App

I could build a full reproduction but it would take a lot of time when the issue is easy to see in the code (it uses tsx!)

Steps to Reproduce the Bug or Issue

  • use virtualRouteConfig and try to build with only bun.

Expected behavior

I would expect tanstack/start to work with bun when using virtualRouteConfig.

Screenshots or Videos

No response

Platform

  • Router / Start Version: 1.134.10 (but the issue is there in latest)
  • OS: mac
  • Browser: n/a
  • Browser Version: n/a
  • Bundler: vite
  • Bundler Version: 6

Additional context

No response

willhoney7 avatar Dec 10 '25 22:12 willhoney7

๐Ÿ“ CodeRabbit Plan Mode

Generate an implementation plan and agent prompts for this issue.

โœ… Successfully generated implementation plan.

๐Ÿ’ก Use @coderabbitai <feedback> to replan

Examples

๐Ÿ”— Similar Issues

Related Issues

๐Ÿ”— Related PRs

TanStack/router#5422 - fix(router-devtools-core): actually bundle solid [merged] TanStack/router#5816 - docs(solid-start): start-bun example [merged] TanStack/router#5847 - docs(solid-start): start-large example [merged] TanStack/router#5849 - docs(solid-start): start-tailwind-v4 [merged]

๐Ÿ‘ค Suggested Assignees

  • birkskyum
  • harrytran998
  • akawahuynh
  • benmccann

๐Ÿงช Issue enrichment is currently in early access.

To disable automatic issue enrichment, add the following to your .coderabbit.yaml:

issue_enrichment:
  auto_enrich:
    enabled: false

coderabbitai[bot] avatar Dec 10 '25 22:12 coderabbitai[bot]

for now you should be able to import the config yourself and pass it in instead of the filename

schiller-manuel avatar Dec 10 '25 22:12 schiller-manuel

for now you should be able to import the config yourself and pass it in instead of the filename

oh. that is a much better solution! thank you!

Maybe passing in a file path should be deprecated and the docs should guide towards passing in the route config object itself?

willhoney7 avatar Dec 10 '25 22:12 willhoney7

Implementation Plan

Approach

Enable TanStack Start's virtualRouteConfig feature to work in Bun runtime by making the config file loading mechanism runtime-aware, allowing it to use Bun's native TypeScript import instead of the Node-specific tsx loader.

Observations

The router-generator package provides utilities for generating TanStack Router route trees from both physical file system structures and virtual route configurations. The virtual route config loader (loadConfigFile.ts) currently uses tsx's tsImport API to dynamically load TypeScript configuration files at runtime. This function is used by both virtual and physical route node generators when loading external or inline route configuration files. The codebase currently assumes a Node.js runtime and uses Node-specific APIs (node:fs, node:path, node:url) throughout.

Assumptions
Assumption 1: Runtime Detection Method

Options Considered:

  • Check typeof Bun !== "undefined" - requires bun-types to avoid TypeScript errors
  • Check process.versions.bun - safer in TypeScript environments and more idiomatic

Chosen Option: Use process.versions.bun for detection

Rationale: This approach is TypeScript-safe, doesn't require additional type definitions, and aligns with standard Node.js version detection patterns. Developers familiar with Node.js will recognize this pattern immediately.

Assumption 2: Scope of Runtime Support

Options Considered:

  • Add support for Bun only
  • Add abstraction layer for multiple runtimes (Bun, Deno, Node)

Chosen Option: Focus solely on Bun support for now

Rationale: The ticket specifically requests Bun support, and adding a more complex abstraction layer would be over-engineering. If Deno or other runtime support is needed later, the runtime detection pattern can be extended following the same approach established here.

๐Ÿ’ก User Tips

Regenerate the plan with different choices with @coderabbitai <feedback>.

Plan

Add Bun Runtime Support to Config File Loading

This phase modifies the config file loading mechanism to detect and handle both Node.js and Bun runtimes, ensuring the virtualRouteConfig feature works in both environments without requiring Node.js installation in Bun-only environments.

Task 1: Add Runtime Detection Logic

Implement runtime detection to determine whether code is executing in Bun or Node.js environment.

  • Add conditional check using process.versions.bun at the start of loadConfigFile function in packages/router-generator/src/filesystem/virtual/loadConfigFile.ts
  • The check should determine which import strategy to use without adding external dependencies
Task 2: Implement Dual Import Strategy

Create separate code paths for Bun's native TypeScript import and Node.js tsx import.

  • For Bun runtime: Use native import() function with the file URL, which Bun handles natively without requiring tsx
  • For Node.js runtime: Preserve existing tsx tsImport logic to maintain backward compatibility
  • Both paths should convert file paths to URLs using pathToFileURL from node:url
  • Both paths must return the same module exports object structure to ensure consistent behavior for downstream consumers
Task 3: Ensure Error Handling Consistency

Update error handling to provide clear feedback regardless of runtime.

  • Catch and handle import failures from both the native import() (Bun) and tsImport (Node) paths
  • Ensure error messages indicate which runtime was detected if import fails
  • Maintain the existing error contract expected by getRouteNodes.ts in both virtual and physical filesystem modules
๐Ÿค– Prompt for AI agents
Modify the config file loading mechanism to support both Bun and Node.js
runtimes, enabling virtualRouteConfig to work in Bun environments.

In `packages/router-generator/src/filesystem/virtual/loadConfigFile.ts`:
- Add runtime detection at the start of `loadConfigFile` using
`process.versions.bun` check
- Implement conditional import strategy: use native `import()` with
`pathToFileURL` for Bun runtime, preserve existing tsx `tsImport` for Node.js
- Ensure both paths convert file paths to URLs and return consistent module
exports structure
- Add error handling for both import paths with runtime-specific error messages
- Maintain backward compatibility and existing error contract for downstream
consumers

๐Ÿš€ Next Steps

๐Ÿค– All AI agent prompts combined
Modify the config file loading mechanism to support both Bun and Node.js
runtimes, enabling virtualRouteConfig to work in Bun environments.

In `packages/router-generator/src/filesystem/virtual/loadConfigFile.ts`:
- Add runtime detection at the start of `loadConfigFile` using
`process.versions.bun` check
- Implement conditional import strategy: use native `import()` with
`pathToFileURL` for Bun runtime, preserve existing tsx `tsImport` for Node.js
- Ensure both paths convert file paths to URLs and return consistent module
exports structure
- Add error handling for both import paths with runtime-specific error messages
- Maintain backward compatibility and existing error contract for downstream
consumers
๐Ÿ’ก Iterate on the plan with: @coderabbitai <feedback>
Example Feedback
- @coderabbitai You can skip phase 3. Add a simple unit test case for phase 2.
- @coderabbitai For assumption 1 go ahead with option 3 and replan.

coderabbitai[bot] avatar Dec 10 '25 22:12 coderabbitai[bot]