BA
Better Auth3mo ago
KZ

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
KZ
KZOP3mo ago
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
KiNFiSH
KiNFiSH3mo ago
It is for a purpose of treeshakable import since zod include the other version on subpathes as well
KZ
KZOP3mo ago
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
KiNFiSH
KiNFiSH3mo ago
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 *
KZ
KZOP3mo ago
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
KiNFiSH
KiNFiSH3mo ago
What package is it breaking ?
KZ
KZOP3mo ago
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
KiNFiSH
KiNFiSH3mo ago
Can you show me the error log ?
KZ
KZOP3mo ago
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
KiNFiSH
KiNFiSH3mo ago
if you also one avoid alias you can do maps with alias -
alias: {
'zod/v4': 'zod'
}
alias: {
'zod/v4': 'zod'
}
KZ
KZOP3mo ago
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
KiNFiSH
KiNFiSH3mo ago
i have to see the stack trace of this. what version of the zod you are using ?
KZ
KZOP3mo ago
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
KiNFiSH
KiNFiSH3mo ago
can you please send me a repro ? i just tried it with vite based project right now . it is fine
KZ
KZOP3mo ago
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
KiNFiSH
KiNFiSH3mo ago
also what is typescript version ?
KZ
KZOP3mo ago
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
KZ
KZOP3mo ago
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
KiNFiSH
KiNFiSH3mo ago
can you please also send your tsconfig ?
KZ
KZOP3mo ago
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 } }
KiNFiSH
KiNFiSH3mo ago
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
KZ
KZOP3mo ago
@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
KiNFiSH
KiNFiSH3mo ago
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.
KZ
KZOP3mo ago
@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

Did you find this page helpful?