get-convex / get-convex/better-auth
react-start entry's dynamic import("@tanstack/react-start/server") pulls the server-SSR graph (node:stream) into client bundles
- Dominant language
- TypeScript
- Stars
- 764
- Forks
- 126
- PR merge metrics
- No merged PRs in 30d
Description
**Versions:** `@convex-dev/better-auth` 0.12.5, `better-auth` 1.6.23, `@tanstack/react-start` 1.168.27, `@tanstack/react-router` 1.170.17, `vite` 7.3.6
## Problem
`convexBetterAuthReactStart` (in `dist/react-start/index.js`) contains, inside its `cachedGetToken` helper:
```js
const { getRequestHeaders } = await import("@tanstack/react-start/server");
```
Per the docs, apps call `convexBetterAuthReactStart(...)` at module scope in a shared file (e.g. `src/lib/auth-server.ts`) and use its returned `fetchAuthQuery`/`getToken` in route loaders. Since loaders are client-reachable, that file lands in the **client** module graph — and Rollup eagerly resolves and bundles dynamic imports, so the whole server-rendering graph comes with it:
`@tanstack/react-start/server` → `@tanstack/react-router/ssr/server` → `@tanstack/router-core/ssr/transformStreamWithRouter` → `node:stream`
The client build then fails:
```
"Readable" is not exported by "__vite-browser-external", imported by
node_modules/@tanstack/router-core/dist/esm/ssr/transformStreamWithRouter.js
```
TanStack Start's import protection doesn't catch it because its default scope only inspects importers inside the app's `srcDirectory` — `node_modules` importers are skipped.
## Workarounds users need today
- `build.rollupOptions.external: [/^node:/]` + `ssr.external` in vite.config — blunt, and still ships ~50 modules of dead server code to the browser; or
- extending `importProtection.include` to this package with `behavior: { build: 'mock' }` — works, but is currently blocked by TanStack/router#7725 in build mode.
## Suggested fix
Keep the client-reachable entry free of any reference to `@tanstack/react-start/server`. E.g.:
- split a `./react-start/server` subpath export for the header-reading code, or
- wrap the `getRequestHeaders` access in TanStack's `createServerOnlyFn` boundary so client builds drop it.
The code only executes server-side already — this is purely a bundling/packaging issue. Happy to test a canary.
Contributor guide
Research direction
Inspect the client-reachable path in dist/react-start/index.js and the package's react-start exports; begin with a client Vite build using the versions and reproduction described. Done means the client build no longer resolves the @tanstack/react-start/server SSR graph or node:stream while the server-side auth behavior remains available.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript, vite
- Domain
- build-system, frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 58/100