Skip to content

fix(react-start): Do not optimizeDeps in VITEST environment - #6074

Open
onlywei wants to merge 3 commits into
TanStack:mainfrom
onlywei:vitest-optimizeDeps
Open

fix(react-start): Do not optimizeDeps in VITEST environment#6074
onlywei wants to merge 3 commits into
TanStack:mainfrom
onlywei:vitest-optimizeDeps

Conversation

@onlywei

@onlywei onlywei commented Dec 12, 2025

Copy link
Copy Markdown
Contributor

Why

Vitest + react-start currently forces optimizeDeps to prebundle React, which can create dual React instances and break hooks. The workaround is disabling the plugin, but then createIsomorphicFn() is never transformed and becomes a no-op.

Fixes #6246 and #6262

Dilemma

Without this fix, I have to give up using either useState(), createIsomorphicFn(), or Vitest. I can’t use all three.

Fix

Skip the aggressive optimizeDeps configuration when process.env.VITEST === 'true', so hooks work and createIsomorphicFn() still transforms.

This is actually just a 1-line fix, the rest is just comments and an e2e test.

Verified

Vitest passes locally without workarounds.

Summary by CodeRabbit

  • Bug Fixes

    • Improved Vitest compatibility by skipping dependency pre-bundling during test runs, helping prevent React hook and environment-related test errors.
  • Tests

    • Added end-to-end coverage for React hooks and client/server environment behavior under Vitest.
    • Added a React test fixture with routing, a counter component, and jsdom-based test configuration.

@coderabbitai

coderabbitai Bot commented Dec 12, 2025

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a Vitest guard to React Start’s Vite plugin so dependency optimization is skipped during Vitest runs. Adds an E2E fixture with React routes, hooks, isomorphic execution, Vitest configuration, and tests validating the behavior.

Changes

React Start Vitest support

Layer / File(s) Summary
Vitest optimizeDeps gating
packages/react-start/src/plugin/vite.ts
Skips optimizeDeps when VITEST is 'true' while preserving existing conditions.
Fixture runtime and routing
e2e/react-start/vitest-hooks/src/*, e2e/react-start/vitest-hooks/package.json
Adds the React counter, isomorphic function, router, root and index routes, generated route tree, and package metadata.
Vitest configuration and validation
e2e/react-start/vitest-hooks/vite.config.ts, e2e/react-start/vitest-hooks/tsconfig.json, e2e/react-start/vitest-hooks/tests/*
Configures Vitest with jsdom and DOM matchers, then verifies hook rendering and client environment selection.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: schiller-manuel

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly states the main change: skipping optimizeDeps when running under Vitest.
Linked Issues check ✅ Passed The plugin now guards optimizeDeps behind a VITEST check and the new Vitest test fixture validates hook rendering and isomorphic behavior.
Out of Scope Changes check ✅ Passed The added Vitest fixture, router scaffolding, and test setup directly support reproducing and verifying the reported issue.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@nx-cloud

nx-cloud Bot commented Dec 12, 2025

Copy link
Copy Markdown
Contributor

View your CI Pipeline Execution ↗ for commit 9fae447

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ✅ Succeeded 9m 28s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 1m 56s View ↗

☁️ Nx Cloud last updated this comment at 2026-02-03 05:13:05 UTC

@pkg-pr-new

pkg-pr-new Bot commented Dec 12, 2025

Copy link
Copy Markdown
More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/arktype-adapter@6074

@tanstack/eslint-plugin-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/eslint-plugin-router@6074

@tanstack/history

npm i https://pkg.pr.new/TanStack/router/@tanstack/history@6074

@tanstack/nitro-v2-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/nitro-v2-vite-plugin@6074

@tanstack/react-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router@6074

@tanstack/react-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-devtools@6074

@tanstack/react-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-ssr-query@6074

@tanstack/react-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start@6074

@tanstack/react-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-client@6074

@tanstack/react-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-server@6074

@tanstack/router-cli

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-cli@6074

@tanstack/router-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-core@6074

@tanstack/router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools@6074

@tanstack/router-devtools-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools-core@6074

@tanstack/router-generator

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-generator@6074

@tanstack/router-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-plugin@6074

@tanstack/router-ssr-query-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-ssr-query-core@6074

@tanstack/router-utils

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-utils@6074

@tanstack/router-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-vite-plugin@6074

@tanstack/solid-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router@6074

@tanstack/solid-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-devtools@6074

@tanstack/solid-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-ssr-query@6074

@tanstack/solid-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start@6074

@tanstack/solid-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-client@6074

@tanstack/solid-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-server@6074

@tanstack/start-client-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-client-core@6074

@tanstack/start-fn-stubs

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-fn-stubs@6074

@tanstack/start-plugin-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-plugin-core@6074

@tanstack/start-server-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-core@6074

@tanstack/start-static-server-functions

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-static-server-functions@6074

@tanstack/start-storage-context

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-storage-context@6074

@tanstack/valibot-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/valibot-adapter@6074

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/TanStack/router/@tanstack/virtual-file-routes@6074

@tanstack/vue-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router@6074

@tanstack/vue-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router-devtools@6074

@tanstack/vue-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router-ssr-query@6074

@tanstack/vue-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start@6074

@tanstack/vue-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start-client@6074

@tanstack/vue-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start-server@6074

@tanstack/zod-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/zod-adapter@6074

commit: 9fae447

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bcce02c and b025a578e6b18424367eee1db7b0ad9cdc8b40a8.

📒 Files selected for processing (1)
  • packages/react-start/src/plugin/vite.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript strict mode with extensive type safety for all code

Files:

  • packages/react-start/src/plugin/vite.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Implement ESLint rules for router best practices using the ESLint plugin router

Files:

  • packages/react-start/src/plugin/vite.ts
🧠 Learnings (1)
📚 Learning: 2025-11-02T16:16:24.898Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5732
File: packages/start-client-core/src/client/hydrateStart.ts:6-9
Timestamp: 2025-11-02T16:16:24.898Z
Learning: In packages/start-client-core/src/client/hydrateStart.ts, the `import/no-duplicates` ESLint disable is necessary for imports from `#tanstack-router-entry` and `#tanstack-start-entry` because both aliases resolve to the same placeholder file (`fake-start-entry.js`) in package.json during static analysis, even though they resolve to different files at runtime.

Applied to files:

  • packages/react-start/src/plugin/vite.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Test
  • GitHub Check: Preview

Comment thread packages/react-start/src/plugin/vite.ts Outdated
@onlywei

onlywei commented Dec 29, 2025

Copy link
Copy Markdown
Contributor Author

Made a repro and an issue: #6246. The problem can be clearly seen there. This PR fixes it.

Comment thread packages/react-start/src/plugin/vite.ts Outdated
@westhouseit

Copy link
Copy Markdown

Thanks @onlywei I hope @schiller-manuel is around today approve and merge. :-)

@onlywei

onlywei commented Jan 16, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @onlywei I hope @schiller-manuel is around today approve and merge. :-)

He's most likely busy making awesome features like React Server Components work. I'll be patient and keep rebasing to resolve lockfile conflicts.

@westhouseit

Copy link
Copy Markdown

He's most likely busy making awesome features like React Server Components work. I'll be patient and keep rebasing to resolve lockfile conflicts.

Absolutely, and I'm using the workaround for now anyway. :-)

@onlywei

onlywei commented Jan 16, 2026

Copy link
Copy Markdown
Contributor Author

He's most likely busy making awesome features like React Server Components work. I'll be patient and keep rebasing to resolve lockfile conflicts.

Absolutely, and I'm using the workaround for now anyway. :-)

Does createIsomorphicFn().server() still work fine for you in vitest without turning on the tanstackStart vite plugin?

@westhouseit

Copy link
Copy Markdown

Does createIsomorphicFn().server() still work fine for you in vitest without turning on the tanstackStart vite plugin?

We're not using any environment functions yet, so it's just the one basic server function using createServerFn().handler() that is working fine. I'm disabling the plugin dynamically in the vite config:

  plugins: [
    !process.env.VITEST && tanstackStart(),
  ].filter(Boolean),

@onlywei

onlywei commented Jan 17, 2026

Copy link
Copy Markdown
Contributor Author

Does createIsomorphicFn().server() still work fine for you in vitest without turning on the tanstackStart vite plugin?

We're not using any environment functions yet, so it's just the one basic server function using createServerFn().handler() that is working fine. I'm disabling the plugin dynamically in the vite config:


  plugins: [

    !process.env.VITEST && tanstackStart(),

  ].filter(Boolean),

I see. Without the Tanstack start vite plugin enabled, it's hard for me to test any isomorphic function.

@onlywei
onlywei force-pushed the vitest-optimizeDeps branch 2 times, most recently from b545524 to 9fae447 Compare February 3, 2026 05:02
@LadyBluenotes

Copy link
Copy Markdown
Member

The repro and coverage here are useful, and #6246 is still open. The Vite plugin has changed since this was last updated, so could you rebase and apply the Vitest guard to the current needsOptimizeDeps logic? After that we can review it against the current plugin.

@onlywei
onlywei force-pushed the vitest-optimizeDeps branch from 9fae447 to bd6b523 Compare July 17, 2026 14:27
@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Note

The previously reviewed commits are no longer reachable (likely due to a force-push or rebase), so CodeRabbit is performing a full review instead of an incremental one. This review may take a little longer.

@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​testing-library/​react@​16.3.210010010087100
Added@​testing-library/​jest-dom@​6.9.110010010089100
Addedjsdom@​27.4.09510010090100
Added@​vitejs/​plugin-react@​5.2.010010010092100

View full report

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
e2e/react-start/vitest-hooks/package.json (1)

10-11: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use workspace:^ instead of workspace:* for internal dependencies in e2e apps.

While the general coding guidelines recommend workspace:*, learnings specific to this repository indicate that workspace:^ is the established convention for e2e test apps, whereas workspace:* is reserved for published/library packages. Consider updating the workspace protocol to match the e2e convention.

♻️ Proposed fix
   "dependencies": {
-    "`@tanstack/react-router`": "workspace:*",
-    "`@tanstack/react-start`": "workspace:*",
+    "`@tanstack/react-router`": "workspace:^",
+    "`@tanstack/react-start`": "workspace:^",
     "react": "^19.2.3",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@e2e/react-start/vitest-hooks/package.json` around lines 10 - 11, Update the
internal dependency declarations for `@tanstack/react-router` and
`@tanstack/react-start` in the package manifest to use the workspace:^ protocol,
matching the established convention for e2e applications instead of workspace:*.

Source: Learnings

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@e2e/react-start/vitest-hooks/package.json`:
- Around line 10-11: Update the internal dependency declarations for
`@tanstack/react-router` and `@tanstack/react-start` in the package manifest to use
the workspace:^ protocol, matching the established convention for e2e
applications instead of workspace:*.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: dd05de0d-5569-4790-8af1-01d06a1d8d2e

📥 Commits

Reviewing files that changed from the base of the PR and between d3e1cf4 and bd6b523.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (12)
  • e2e/react-start/vitest-hooks/package.json
  • e2e/react-start/vitest-hooks/src/components/Counter.tsx
  • e2e/react-start/vitest-hooks/src/isomorphic.ts
  • e2e/react-start/vitest-hooks/src/routeTree.gen.ts
  • e2e/react-start/vitest-hooks/src/router.tsx
  • e2e/react-start/vitest-hooks/src/routes/__root.tsx
  • e2e/react-start/vitest-hooks/src/routes/index.tsx
  • e2e/react-start/vitest-hooks/tests/setup.ts
  • e2e/react-start/vitest-hooks/tests/vitest.spec.tsx
  • e2e/react-start/vitest-hooks/tsconfig.json
  • e2e/react-start/vitest-hooks/vite.config.ts
  • packages/react-start/src/plugin/vite.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/react-start/src/plugin/vite.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

react-start + vitest: Cannot read properties of null (reading 'useState')

4 participants