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

Open
#409 1 comment 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.