Skip to content

Vite plugin adds src/entry-client.tsx as second client rollup input when used with TanStack Start (regression in 20260227-181935) #4069

@scottdraper8

Description

@scottdraper8

Environment

nitro-nightly 3.0.1-20260227-181935-bfbb207c  (broken)
nitro-nightly 3.0.1-20260227-142232-5ccf672a  (works — both from 2026-02-27)
@tanstack/react-start 1.162.9
vite 7.3.1
node 22

Reproduction

Minimal vite.config.ts:

import { defineConfig } from 'vite'
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
import { nitro } from 'nitro/vite'
import viteReact from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [tanstackStart(), nitro(), viteReact()],
})

With a src/entry-client.tsx that looks like any standard TanStack Start client entry:

import { StartClient } from '@tanstack/react-start/client'
import { StrictMode } from 'react'
import { hydrateRoot } from 'react-dom/client'

hydrateRoot(document, <StrictMode><StartClient /></StrictMode>)

Describe the bug

After upgrading from the 142232 nightly to 181935, the client Rollup build input contains two entries instead of one:

{
  "main": "virtual:tanstack-start-client-entry",
  "index": "/absolute/path/to/src/entry-client.tsx"
}

Only main should be there. TanStack Start registers virtual:tanstack-start-client-entry → src/entry-client.tsx as an alias and sets environments.client.build.rollupOptions.input to { main: "virtual:tanstack-start-client-entry" }. The 181935 nightly then also picks up src/entry-client.tsx directly (via what looks like a scanDirs scan for entry-client.*) and adds it as a separate index input to the same environment. The client bundle ends up broken as a result.

Rolling back to the 142232 nightly or manually pinning the lockfile to it fixes it.

Additional context

The index key in the duplicate entry matches what createServiceEnvironment produces ({ input: { index: entry } }), so the regression is likely in the configEnvironment hook — either the early return for consumer === "client" environments was broken, or the client entry auto-detection now runs before or after that check in a way it didn't before.

There's no config-level workaround; renderer is excluded from NitroConfig/NitroPluginConfig so there's no way to suppress the discovery from userland.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions