diff --git a/packages/plugin-rsc/e2e/basic.test.ts b/packages/plugin-rsc/e2e/basic.test.ts
index 5a0464a09..d463b983b 100644
--- a/packages/plugin-rsc/e2e/basic.test.ts
+++ b/packages/plugin-rsc/e2e/basic.test.ts
@@ -11,9 +11,6 @@ import {
 import path from 'node:path'
 import os from 'node:os'
 
-// TODO: parallel?
-// TODO: all tests don't need to be tested in all variants?
-
 test.describe('dev-default', () => {
   const f = useFixture({ root: 'examples/basic', mode: 'dev' })
   defineTest(f)
@@ -824,6 +821,14 @@ function defineTest(f: Fixture) {
     )
   })
 
+  test('transitive cjs dep', async ({ page }) => {
+    await page.goto(f.url())
+    await waitForHydration(page)
+    await expect(page.getByTestId('transitive-cjs-client')).toHaveText(
+      'ok:browser',
+    )
+  })
+
   test('use cache function', async ({ page }) => {
     await page.goto(f.url())
     await waitForHydration(page)
diff --git a/packages/plugin-rsc/examples/basic/package.json b/packages/plugin-rsc/examples/basic/package.json
index 43d95645d..6fb6344bc 100644
--- a/packages/plugin-rsc/examples/basic/package.json
+++ b/packages/plugin-rsc/examples/basic/package.json
@@ -21,6 +21,7 @@
     "@types/react": "^19.1.8",
     "@types/react-dom": "^19.1.6",
     "@vitejs/plugin-react": "latest",
+    "@vitejs/test-dep-transitive-cjs": "file:./test-dep/transitive-cjs",
     "@vitejs/test-dep-client-in-server": "file:./test-dep/client-in-server",
     "@vitejs/test-dep-client-in-server2": "file:./test-dep/client-in-server2",
     "@vitejs/test-dep-server-in-client": "file:./test-dep/server-in-client",
diff --git a/packages/plugin-rsc/examples/basic/src/routes/deps/transitive-cjs/client.tsx b/packages/plugin-rsc/examples/basic/src/routes/deps/transitive-cjs/client.tsx
new file mode 100644
index 000000000..11045ee39
--- /dev/null
+++ b/packages/plugin-rsc/examples/basic/src/routes/deps/transitive-cjs/client.tsx
@@ -0,0 +1,12 @@
+'use client'
+
+// @ts-ignore
+import { TestClient } from '@vitejs/test-dep-transitive-cjs/client'
+
+export function TestTransitiveCjsClient() {
+  return (
+    
+      [test-dep-transitive-cjs-client: ]
+    
+  )
+}
diff --git a/packages/plugin-rsc/examples/basic/src/routes/root.tsx b/packages/plugin-rsc/examples/basic/src/routes/root.tsx
index 52ce38dee..f679c362e 100644
--- a/packages/plugin-rsc/examples/basic/src/routes/root.tsx
+++ b/packages/plugin-rsc/examples/basic/src/routes/root.tsx
@@ -29,6 +29,7 @@ import { TestTemporaryReference } from './temporary-reference/client'
 import { TestUseCache } from './use-cache/server'
 import { TestHydrationMismatch } from './hydration-mismatch/server'
 import { TestBrowserOnly } from './browser-only/client'
+import { TestTransitiveCjsClient } from './deps/transitive-cjs/client'
 
 export function Root(props: { url: URL }) {
   return (
@@ -67,6 +68,7 @@ export function Root(props: { url: URL }) {
         
         
         
+        
         
         
         
diff --git a/packages/plugin-rsc/examples/basic/test-dep/transitive-cjs/client.js b/packages/plugin-rsc/examples/basic/test-dep/transitive-cjs/client.js
new file mode 100644
index 000000000..db2fd4b6f
--- /dev/null
+++ b/packages/plugin-rsc/examples/basic/test-dep/transitive-cjs/client.js
@@ -0,0 +1,27 @@
+'use client'
+
+import React from 'react'
+
+// similar to swr
+// https://github.com/vercel/swr/blob/063fe55dddb95f0b6c3f1637a935c43d732ded78/src/index/use-swr.ts#L3
+import { useSyncExternalStore } from 'use-sync-external-store/shim/index.js'
+
+const h = React.createElement
+
+const noopStore = () => () => {}
+
+export function TestClient() {
+  const value = useSyncExternalStore(
+    noopStore,
+    () => 'ok:browser',
+    () => 'ok:ssr',
+  )
+
+  return h(
+    'span',
+    {
+      'data-testid': 'transitive-cjs-client',
+    },
+    value,
+  )
+}
diff --git a/packages/plugin-rsc/examples/basic/test-dep/transitive-cjs/package.json b/packages/plugin-rsc/examples/basic/test-dep/transitive-cjs/package.json
new file mode 100644
index 000000000..8368742da
--- /dev/null
+++ b/packages/plugin-rsc/examples/basic/test-dep/transitive-cjs/package.json
@@ -0,0 +1,14 @@
+{
+  "name": "@vitejs/test-dep-transitive-cjs",
+  "private": true,
+  "type": "module",
+  "exports": {
+    "./client": "./client.js"
+  },
+  "dependencies": {
+    "use-sync-external-store": "^1.5.0"
+  },
+  "peerDependencies": {
+    "react": "*"
+  }
+}
diff --git a/packages/plugin-rsc/examples/basic/vite.config.ts b/packages/plugin-rsc/examples/basic/vite.config.ts
index 97d0f30b8..b0eec5511 100644
--- a/packages/plugin-rsc/examples/basic/vite.config.ts
+++ b/packages/plugin-rsc/examples/basic/vite.config.ts
@@ -135,12 +135,29 @@ export default { fetch: handler };
     minify: false,
     manifest: true,
   },
-  optimizeDeps: {
-    exclude: [
-      '@vitejs/test-dep-client-in-server/client',
-      '@vitejs/test-dep-client-in-server2/client',
-      '@vitejs/test-dep-server-in-client/client',
-    ],
+  environments: {
+    client: {
+      optimizeDeps: {
+        entries: [
+          './src/routes/**/client.tsx',
+          './src/framework/entry.browser.tsx',
+        ],
+        exclude: [
+          '@vitejs/test-dep-client-in-server/client',
+          '@vitejs/test-dep-client-in-server2/client',
+          '@vitejs/test-dep-server-in-client/client',
+        ],
+      },
+    },
+    ssr: {
+      optimizeDeps: {
+        // TODO: this should be somehow auto inferred or at least show a warning
+        // to guide users to `optimizeDeps.include`
+        include: [
+          '@vitejs/test-dep-transitive-cjs > use-sync-external-store/shim/index.js',
+        ],
+      },
+    },
   },
 }) as any
 
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 8bd988406..8b1fa0154 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -542,6 +542,9 @@ importers:
       '@vitejs/test-dep-server-in-server':
         specifier: file:./test-dep/server-in-server
         version: file:packages/plugin-rsc/examples/basic/test-dep/server-in-server(react@19.1.0)
+      '@vitejs/test-dep-transitive-cjs':
+        specifier: file:./test-dep/transitive-cjs
+        version: file:packages/plugin-rsc/examples/basic/test-dep/transitive-cjs(react@19.1.0)
       rsc-html-stream:
         specifier: ^0.0.7
         version: 0.0.7
@@ -3094,6 +3097,11 @@ packages:
     peerDependencies:
       react: '*'
 
+  '@vitejs/test-dep-transitive-cjs@file:packages/plugin-rsc/examples/basic/test-dep/transitive-cjs':
+    resolution: {directory: packages/plugin-rsc/examples/basic/test-dep/transitive-cjs, type: directory}
+    peerDependencies:
+      react: '*'
+
   '@vitest/expect@3.2.4':
     resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==}
 
@@ -5536,6 +5544,11 @@ packages:
   uri-js@4.4.1:
     resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
 
+  use-sync-external-store@1.5.0:
+    resolution: {integrity: sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+
   util-deprecate@1.0.2:
     resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
 
@@ -7656,6 +7669,11 @@ snapshots:
     dependencies:
       react: 19.1.0
 
+  '@vitejs/test-dep-transitive-cjs@file:packages/plugin-rsc/examples/basic/test-dep/transitive-cjs(react@19.1.0)':
+    dependencies:
+      react: 19.1.0
+      use-sync-external-store: 1.5.0(react@19.1.0)
+
   '@vitest/expect@3.2.4':
     dependencies:
       '@types/chai': 5.2.2
@@ -10440,6 +10458,10 @@ snapshots:
     dependencies:
       punycode: 2.3.1
 
+  use-sync-external-store@1.5.0(react@19.1.0):
+    dependencies:
+      react: 19.1.0
+
   util-deprecate@1.0.2: {}
 
   valibot@0.41.0(typescript@5.8.3):