Skip to content

fix(auth): match the dev better-auth client aliases exactly - #587

Merged
Brooooooklyn merged 2 commits into
mainfrom
fix/better-auth-alias-subpaths
Oct 26, 2026
Merged

Brooooooklyn merged 2 commits into
mainfrom
fix/better-auth-alias-subpaths

Conversation

@Brooooooklyn

Copy link
Copy Markdown
Member

Fixes #565

Problem

With auth on, vp dev aliases five better-auth subpaths to files in Void's own copy of better-auth. Each alias used a string find, and in Vite a string find also matches every deeper path:

alias find 'better-auth/client'  →  …/better-auth/dist/client/index.mjs

import 'better-auth/client'          →  …/dist/client/index.mjs          ✓
import 'better-auth/client/plugins'  →  …/dist/client/index.mjs/plugins  ✗ (no such file)

So any app that passes a Better Auth client plugin (adminClient(), organizationClient(), …) to createAuthClient broke in dev:

  • the client failed with Failed to resolve import "better-auth/client/plugins";
  • SSR returned 500 (No such module …).

vp build adds no alias, so it was fine.

Fix

Each find is now an anchored RegExp, ^better-auth/<sub>$. Vite's alias API has only two kinds of find: a string, which also matches deeper paths, or a RegExp. So a RegExp is the only way to get an exact match. The repo already does the same ({ find: /^void$/ } in cli/wrapper.ts).

                                 before (string)        after (exact)
better-auth/client               Void's copy ✓          Void's copy ✓   (unchanged)
better-auth/react|vue|svelte|solid  Void's copy ✓       Void's copy ✓   (unchanged)
better-auth/client/plugins       broken path ✗          normal resolution ✓

The five exact ids get the same replacement in every Vite step that reads resolve.alias:

  • the alias plugin;
  • vite:pre-alias;
  • SSR externalization;
  • the dependency optimizer.

So the cold-cache reload protection from #24 (the reason the aliases exist) is kept.

Checks

  • New test in plugin-routing.test.ts. It starts a real Vite dev server with auth on and resolves:

    • better-auth/client and /react from an app file, which has no better-auth of its own. They resolve only through the aliases, to Void's copy.
    • better-auth/client/plugins from inside the package. It resolves to dist/client/plugins/index.mjs.
  • Mutation check: the test fails with the old string find and with no aliases at all.

  • Scratch app from the issue: a React pages app, auth on, adminClient() from better-auth/client/plugins, cold cache, vp dev.

                     before                     after
    SSR  GET /       500 No such module         200, authClient.admin.listUsers is a function
    client module    500 Failed to resolve      200
    
  • void typecheck, lint and fmt pass. Affected tests (vp run test, 508 files) pass.

Not changed here

  • client/plugins is not pinned to Void's copy. The issue mentions this as optional. Without it, the user's own better-auth provides client/plugins, as in vp build, and Vite discovers it like any other dependency. That costs one optimizer reload on the first cold-cache page that imports it. Pinning would point the import at Void's better-auth version instead of the one the app installed. That's a product decision, so I left it out.

🤖 Generated with Claude Code

With auth on, `vp dev` aliases `better-auth/client`, `/react`, `/vue`,
`/svelte` and `/solid` to files in Void's own better-auth. A string alias
also matches every deeper path, so `better-auth/client/plugins` (where
`adminClient()` and the other client plugins live) became
`.../dist/client/index.mjs/plugins`, and apps using a client plugin failed
in dev on both the client and SSR. Builds have no alias and were fine.

Use an anchored RegExp for each alias, which is Vite's only exact match.
The five exact ids resolve as before; deeper subpaths resolve normally.

Fixes #565

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Brooooooklyn

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review 🔄 Running since 2026-10-26T03:38:29.632520Z 822d013 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

🚀 Deploying Preview to Cloudflare 🚀

Preview URL: https://fix-better-auth-alias-subpaths-void-cloud.voidzero-docs.workers.dev (commit 67d306e)

This URL reflects your latest Preview deployment

Preview Deployments by commit

Status Deployment URL Commit Updated (UTC) See this deployment's details
  • Build: Success ✅
  • Deployment: Success ✅

View logs ↗
https://c5806793-void-cloud.voidzero-docs.workers.dev 67d306e 2026-10-26T03:54:25.736Z Visit the dashboard ↗
  • Build: Success ✅
  • Deployment: Success ✅

View logs ↗
https://68e6cfa7-void-cloud.voidzero-docs.workers.dev 822d013 2026-10-26T03:39:05.906Z Visit the dashboard ↗

Comment thread packages/void/src/plugin-routing.ts Outdated
cpojer
cpojer previously approved these changes Oct 26, 2026
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Brooooooklyn
Brooooooklyn merged commit b209501 into main Oct 26, 2026
20 checks passed
@Brooooooklyn
Brooooooklyn deleted the fix/better-auth-alias-subpaths branch October 26, 2026 04:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dev: better-auth/client/plugins fails to resolve when auth is enabled (the better-auth/client alias matches it as a prefix)

2 participants