Login And Bundle Debugging Notes
Date: 2026-06-12
What I observed#
apps/osdev sign-in can look like a no-op if the user clicks the SSR-rendered button before the client has hydrated.- In a Playwright repro against
http://localhost:61975/sign-in?redirect_url=%2F, an immediate click produced no/api/iterate-auth/loginrequest. Waiting longer before clicking produced the expected request:GET /api/iterate-auth/login?return_to=%2F. - The slow hydration is made worse because the OS dev client loads
src/start.ts, thensrc/auth/middleware.ts, thenapps/auth/src/lib/server.ts. That pulls server auth code into the dev client graph before the sign-in button handler is active. - The auth worker build also has a large startup surface. A synthetic esbuild bundle of
apps/auth/src/server/worker.tswas about3.75 MBunminified without code splitting.
Likely login fixes#
-
Make the OS sign-in control a real link to
/api/iterate-auth/login?return_to=...instead of a JS-only button. This makes the browser navigate even before React hydration finishes. -
Keep OS request middleware server-heavy imports behind a server boundary. The direct
apps/os/src/start.ts -> apps/os/src/auth/middleware.ts -> @iterate-com/auth/serverchain is a dev hydration cost and makes early clicks unreliable. -
Keep the random OS dev port stable across clean restarts. OAuth redirect URLs include the random port, so changing ports makes local auth harder to reason about and can leave browser state/bookmarks pointing at the wrong callback URL.
Auth Bundle Findings#
Synthetic bundle command used:
pnpm --dir apps/os exec esbuild ../../apps/auth/src/server/worker.ts \
--bundle --splitting --format=esm --platform=browser --target=es2022 \
--define:process.env.NODE_ENV='"production"' \
'--external:cloudflare:workers' '--external:node:*' \
'--external:__STATIC_CONTENT_MANIFEST' \
'--external:#tanstack-router-entry' '--external:#tanstack-start-entry' \
'--external:tanstack-start-manifest:v' \
'--external:tanstack-start-injected-head-scripts:v' \
--metafile=/tmp/auth-worker-prod-split-meta.json \
--outdir=/tmp/auth-worker-prod-splitTop source contributors from the metafile:
better-auth: about914 KBkysely: about635 KBzod: about537 KBreact-dom: about515 KBin production-mode input bytes@opentelemetry/semantic-conventions: about280 KB@tanstack/router-core: about194 KB@better-auth/oauth-provider: about156 KBsqlfu: about146 KB
Likely Auth Optimizations#
-
Lazy-load
@tanstack/react-start/server-entryinside the fallbackapp.all("*")route inapps/auth/src/server/worker.ts. API requests under/api/auth/*,/api/orpc/*, discovery routes, and/logoutdo not need React SSR at startup. -
Replace the Better Auth plugin barrel import in
apps/auth/src/server/auth-plugins.ts. Current import:
import { bearer, deviceAuthorization, emailOTP, jwt, oneTimeToken } from "better-auth/plugins";Direct imports are available and should avoid pulling unused plugin modules such as open-api and mcp:
import { bearer } from "better-auth/plugins/bearer";
import { deviceAuthorization } from "better-auth/plugins/device-authorization";
import { emailOTP } from "better-auth/plugins/email-otp";
import { jwt } from "better-auth/plugins/jwt";
import { oneTimeToken } from "better-auth/plugins/one-time-token";-
Investigate why
@opentelemetry/semantic-conventionsis in the auth worker bundle. The likely path is through oRPC plugins or shared server dependencies. If auth does not need telemetry metadata on the login path, isolate that import behind the oRPC route or a lazy module. -
Consider splitting the auth API worker from the React UI worker if cold starts remain slow. The current worker statically combines Better Auth, oRPC, DB/query helpers, and TanStack Start SSR.
Verification Already Run#
pnpm --dir apps/auth typecheckpnpm --dir apps/os typecheck- Playwright repro confirming immediate pre-hydration click did not request login, while a later click did.
- Temporary local-dev-server check confirmed preserving the
.dev-serverstate file would allow reuse of the same random port when still free.