subpath imports of zod/v4 in 1.3.x breaks prod build when conflicting packages using v4 do not
Is there a reason we are keeping the explicit subpath imports in better-auth now that we have bumped up to 4.0.5?
24 Replies
this maybe a vite issue
but if better-auth@1.3.3 and for instance better-auth-ui are both using zod@4.0.5
but better-auth-ui is not making explicit subpath imports
then vite has a type error inside better-auth at db/schema.ts when you are creating accountschema.
I tested against 1.3.3 locally after changing all "zod/v4" back to "zod" no issues.
are we waiting to remove these explicit subpath imports?
@KiNFiSH hey the migration to explicit subath zod/v4 is there a reason the packages need to use that?
now that 1.3.3 has bumped up to zod 4.0.x
It is for a purpose of treeshakable import since zod include the other version on subpathes as well
i think the issue with this now is that other packages that use zod@4 will conflict this with this.
also i think zod/mini is what people are targeting for treeshacking performance updates
Mini is limited on some cases but when you do the subpath import for v4. It is auto treeshaked against other version of zod since they still exists
Along with import with *
ok the problem is that i can definitely see it causing issues now because when vite is bundling this the package is almost identical but that because of the way subpath imports work this will break other packages
What package is it breaking ?
any package that is on the same version >4.0.0 as better-auth and calls import * z from "zod" vs better-auth's import * a z from "zod/v4"
vite is getting confused on the subpath imports when bundling because they are pointing to the same things just when it bundles it gets confused i'm seeing alot of ZodString2
Can you show me the error log ?
ya one second i have to undo some stuff
bane of my existence vite but this is also about how subpath imports work when you're doing funky stuff like zod did with v4
if you also one avoid alias you can do maps with alias -
i already tried that the issue there is you break more
because there's also zod/v4/core now vs ./core
its really stupid
yes i know that's what i first did then it blew up more
i have to see the stack trace of this.
what version of the zod you are using ?
yup i know
4.0.5
and i'm not even using it
this any package that will be combined with better-auth
so better-auth-ui breaks
worse its that its a prod not a dev issue
can you please send me a repro ? i just tried it with vite based project right now . it is fine
in prod one sec
✘ [ERROR] service core:user:nivalis-advisors: Uncaught TypeError: Class2 is not a constructor
at null.<anonymous> (worker-entry.js:12386:10) in _string
at null.<anonymous> (worker-entry.js:13098:10) in string2
at null.<anonymous> (worker-entry.js:152024:7)
one sec
worker-entry.js:12386:10
// node_modules/.pnpm/zod@4.0.5/node_modules/zod/v4/core/api.js
function _string(Class2, params) {
return new Class2({
type: "string",
...normalizeParams(params)
});
}
at null.<anonymous> (worker-entry.js:13098:10) in string2
// node_modules/.pnpm/zod@4.0.5/node_modules/zod/v4/classic/schemas.js
function string2(params) {
return _string(ZodString2, params);
}
at null.<anonymous> (worker-entry.js:152024:7)
// node_modules/.pnpm/better-auth@1.3.3_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/better-auth/dist/shared/better-auth.n2KFGwjY.mjs
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
var accountSchema = object({
id: string2(),
providerId: string2(),
accountId: string2(),
userId: coerce_exports.string(),
accessToken: string2().nullish(),
refreshToken: string2().nullish(),
idToken: string2().nullish(),
/**
* Access token expires at
*/
sry one sec
also what is typescript version ?
GitHub
Blaming better-auth/packages/better-auth/src/db/schema.ts at e11c51...
The most comprehensive authentication framework for TypeScript - Blaming better-auth/packages/better-auth/src/db/schema.ts at e11c51e210cbc9c4b7177e13a9c8efd2985c856f · better-auth/better-auth
5.8.3
i am going to try 5.9 at some point but either way you can see whats happening
basically it thinks zod been initialized because the bundling gets confused by the subpaths
all the tsconfig is correct
can you please also send your tsconfig ?
if i clone locally 1.3.3 and change all of the explicit zod/v4 this work s
{
"extends": "./tsconfig.json",
"include": [
".react-router/types//*",
"app//",
"app//.server//",
"app//.client//",
"app/insights/**/",
"workers/*/"
],
"compilerOptions": {
"allowArbitraryExtensions": true,
"declaration": false,
"declarationMap": false,
"strict": true,
"lib": ["DOM", "DOM.Iterable", "ES2022"],
"types": ["vite/client", "./worker-configuration.d.ts"],
"target": "ES2022",
"module": "ES2022",
"moduleResolution": "bundler",
"noEmit": false,
"jsx": "react-jsx",
"baseUrl": ".",
"rootDirs": [".", "./.react-router/types"],
"paths": {
"~/": ["./app/"],
"@/": ["./app/"]
},
"resolveJsonModule": true
}
}
I’m gonna look for what Colin did in terms of type alias on zod in the recent changes and will try to see more on repro as well
@bekacru @KiNFiSH no worries i'm probably one of the first this is hapenning to but like i said subpath imports get tricky for the bundler when they are shalow aliases and the waterfall for export to import are not done with the intention of performance instead of the alias
i'll build the draft pr and the test project for the break using my template
i'll mention as well ttyl
tl;dr @bekacru potential bug in when better-auth imports from "zod/v4" and another package using the same zod package version goes direct
in prod.
not in dev and i can't alias around it because of zod/v4/core also existing
yeah may be i can also inspect some stuff on rollup and esbuild to make it much easier on point out the issue. also will try to look on overrides or resolutions mechanism on handling noting the bundler that the references are the same since the bundler is having a hard time on resolution.
but make sure to send me the repro template if possible and will look into the collin commit till then.
@KiNFiSH @bekacru tl;dr this a highly specific issue to the combination of vite combined cloudflare BUT w/o using the cloudflare vite plugin
i'm not sure you are going to see this as much as i thought
vite can't handle subpath imports as well as i thinks it can when building this for webworker target PLUS using separated ssr environments with multiple entrypoints. my guess its deep in rollup
ignore this for now, i'm sorry for the redflag but I'm trying to get around alot of issues merging a bunch of capabilties in the project. mainly an integrated single project rrv7 in cloudlfare with partial prerendering and durable objects and other cloudflare: specific imports that can't be dynamic imported
fixed my issue but i'm at my limit with trying to do this because another thing will eventually break and remix team is about to abandon progress on react-router for remix v3
i'm splitting up usage of better-auth into a monorepo consisting of two or more workers. one for the api and one for the site. apologies
i'll create a template eventually. vite f'ing me again.
i think thats what @cloudflare/vite fixes along with abunch of other stuff. wish i could use it but it break partial prerendering