[GH-ISSUE #3136] Module not found: Can't resolve 'tls' ( drizzle-orm/singlestore ) #9487

Closed
opened 2026-04-13 04:58:12 -05:00 by GiteaMirror · 8 comments
Owner

Originally created by @SkidGod4444 on GitHub (Jun 22, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/3136

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

After configuring drizzle orm with singlestore, am not able to call the authClient from client side. It throws this error.

 ./node_modules/mysql2/lib/base/connection.js:19:13
Module not found: Can't resolve 'tls'
  17 |
  18 | const Net = require('net');
> 19 | const Tls = require('tls');
     |             ^^^^^^^^^^^^^^
  20 | const Timers = require('timers');
  21 | const EventEmitter = require('events').EventEmitter;
  22 | const Readable = require('stream').Readable;



https://nextjs.org/docs/messages/module-not-found

My DB config:

import { drizzle } from 'drizzle-orm/singlestore';
import { Envs } from '@prexo/utils/envs';

export const db = drizzle({ connection: { uri: Envs.DATABASE_URL }});;

Current vs. Expected behavior

This is something that should not happen on the client side. I understand it's a peer dependency issue, but what do I do now?

What version of Better Auth are you using?

1.2.8

Provide environment information

- OS: (Mac)
- Browser: (Chrome)

Which area(s) are affected? (Select all that apply)

Client

Auth config (if applicable)

import { betterAuth } from "better-auth";
import { db } from "@prexo/db";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { Envs } from "@prexo/utils/envs";
import { passkey } from "better-auth/plugins/passkey"
import { haveIBeenPwned } from "better-auth/plugins"
import { createAuthClient } from "better-auth/client"
import { passkeyClient } from "better-auth/client/plugins"
// import { polar, checkout, portal, usage, webhooks } from "@polar-sh/better-auth";
// import { Polar } from "@polar-sh/sdk";
// import { polarClient } from "@polar-sh/better-auth";

export const authClient = createAuthClient({
    plugins: [ 
        passkeyClient(),
        // polarClient(),
    ] 
})

// const polarInit = new Polar({
//     accessToken: Envs.POLAR_ACCESS_TOKEN,
//     // Use 'sandbox' if you're using the Polar Sandbox environment
//     // Remember that access tokens, products, etc. are completely separated between environments.
//     // Access tokens obtained in Production are for instance not usable in the Sandbox environment.
//     server: 'sandbox'
// });

export const auth: ReturnType<typeof betterAuth> = betterAuth({
    database: drizzleAdapter(db, {
        provider: "mysql", // or "pg", "sqlite"
    }),
    plugins: [ 
        passkey(), 
        haveIBeenPwned({
            customPasswordCompromisedMessage: "Please choose a more secure password."
        }),
        // polar({
        //     client: polarInit,
        //     createCustomerOnSignUp: true,
        //     use: [
        //         checkout({
        //             products: [
        //                 {
        //                     productId: "123-456-789", // ID of Product from Polar Dashboard
        //                     slug: "pro" // Custom slug for easy reference in Checkout URL, e.g. /checkout/pro
        //                 }
        //             ],
        //             successUrl: "/success?checkout_id={CHECKOUT_ID}",
        //             authenticatedUsersOnly: true
        //         }),
        //         portal(),
        //         usage(),
        //         webhooks({
        //             secret: Envs.POLAR_WEBHOOK_SECRET,
        //             // onCustomerStateChanged: (payload: any) => {
        //             //     // Triggered when anything regarding a customer changes
        //             // },
        //             // onOrderPaid: (payload: any) => {
        //             //     // Triggered when an order was paid (purchase, subscription renewal, etc.)
        //             // },
        //             // onPayload: (payload: any) => {
        //             //     // Catch-all for all events
        //             // }
        //         })
        //     ],
        // })
    ], 
    trustedOrigins: ["*"],
    socialProviders: {
        github: {
          clientId: Envs.GITHUB_CLIENT_ID,
          clientSecret: Envs.GITHUB_CLIENT_SECRET,
        },
        discord: {
          clientId: Envs.DISCORD_CLIENT_ID,
          clientSecret: Envs.DISCORD_CLIENT_SECRET,
        },
        google: {
          clientId: Envs.GOOGLE_CLIENT_ID,
          clientSecret: Envs.GOOGLE_CLIENT_SECRET,
        },
      },
    baseURL: Envs.BETTER_AUTH_URL,
    secret: Envs.BETTER_AUTH_SECRET,
})

Additional context

No response

Originally created by @SkidGod4444 on GitHub (Jun 22, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/3136 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce After configuring drizzle orm with singlestore, am not able to call the authClient from client side. It throws this error. ```ts ⨯ ./node_modules/mysql2/lib/base/connection.js:19:13 Module not found: Can't resolve 'tls' 17 | 18 | const Net = require('net'); > 19 | const Tls = require('tls'); | ^^^^^^^^^^^^^^ 20 | const Timers = require('timers'); 21 | const EventEmitter = require('events').EventEmitter; 22 | const Readable = require('stream').Readable; https://nextjs.org/docs/messages/module-not-found ``` My DB config: ```ts import { drizzle } from 'drizzle-orm/singlestore'; import { Envs } from '@prexo/utils/envs'; export const db = drizzle({ connection: { uri: Envs.DATABASE_URL }});; ``` ### Current vs. Expected behavior This is something that should not happen on the client side. I understand it's a peer dependency issue, but what do I do now? ### What version of Better Auth are you using? 1.2.8 ### Provide environment information ```bash - OS: (Mac) - Browser: (Chrome) ``` ### Which area(s) are affected? (Select all that apply) Client ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth"; import { db } from "@prexo/db"; import { drizzleAdapter } from "better-auth/adapters/drizzle"; import { Envs } from "@prexo/utils/envs"; import { passkey } from "better-auth/plugins/passkey" import { haveIBeenPwned } from "better-auth/plugins" import { createAuthClient } from "better-auth/client" import { passkeyClient } from "better-auth/client/plugins" // import { polar, checkout, portal, usage, webhooks } from "@polar-sh/better-auth"; // import { Polar } from "@polar-sh/sdk"; // import { polarClient } from "@polar-sh/better-auth"; export const authClient = createAuthClient({ plugins: [ passkeyClient(), // polarClient(), ] }) // const polarInit = new Polar({ // accessToken: Envs.POLAR_ACCESS_TOKEN, // // Use 'sandbox' if you're using the Polar Sandbox environment // // Remember that access tokens, products, etc. are completely separated between environments. // // Access tokens obtained in Production are for instance not usable in the Sandbox environment. // server: 'sandbox' // }); export const auth: ReturnType<typeof betterAuth> = betterAuth({ database: drizzleAdapter(db, { provider: "mysql", // or "pg", "sqlite" }), plugins: [ passkey(), haveIBeenPwned({ customPasswordCompromisedMessage: "Please choose a more secure password." }), // polar({ // client: polarInit, // createCustomerOnSignUp: true, // use: [ // checkout({ // products: [ // { // productId: "123-456-789", // ID of Product from Polar Dashboard // slug: "pro" // Custom slug for easy reference in Checkout URL, e.g. /checkout/pro // } // ], // successUrl: "/success?checkout_id={CHECKOUT_ID}", // authenticatedUsersOnly: true // }), // portal(), // usage(), // webhooks({ // secret: Envs.POLAR_WEBHOOK_SECRET, // // onCustomerStateChanged: (payload: any) => { // // // Triggered when anything regarding a customer changes // // }, // // onOrderPaid: (payload: any) => { // // // Triggered when an order was paid (purchase, subscription renewal, etc.) // // }, // // onPayload: (payload: any) => { // // // Catch-all for all events // // } // }) // ], // }) ], trustedOrigins: ["*"], socialProviders: { github: { clientId: Envs.GITHUB_CLIENT_ID, clientSecret: Envs.GITHUB_CLIENT_SECRET, }, discord: { clientId: Envs.DISCORD_CLIENT_ID, clientSecret: Envs.DISCORD_CLIENT_SECRET, }, google: { clientId: Envs.GOOGLE_CLIENT_ID, clientSecret: Envs.GOOGLE_CLIENT_SECRET, }, }, baseURL: Envs.BETTER_AUTH_URL, secret: Envs.BETTER_AUTH_SECRET, }) ``` ### Additional context _No response_
GiteaMirror added the locked label 2026-04-13 04:58:12 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Jun 22, 2025):

Hi @SkidGod4444! I'm Dosu and I’m helping the better-auth team.

This error happens because Node.js modules like tls (used by mysql2 and thus drizzle-orm/singlestore) are only available on the server, not in the browser. If you see this error on the client, it means some server-only code—like your DB config or the drizzleAdapter—is being imported into a client-side bundle.

To fix this, make sure all database and adapter code (like your db and auth objects) live in server-only files (for example, in /lib/server or /api). Only import and use them in API routes, server actions, or other server-side code. On the client, only use client-safe APIs like createAuthClient and client plugins. Never import your DB config or drizzleAdapter into client components or pages.

You can see this separation in the Better Auth Next.js demo, where server-side auth logic is handled in API routes, and client pages only use client utilities—never the DB or adapter code.

If you restructure your code so that server-only modules are never imported on the client, this error will go away. If you need to share types or helpers, put them in separate files that don’t import server-only code.

Let me know if you want a concrete example or help reorganizing your files!

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Join Discord Share on X

<!-- gh-comment-id:2994387465 --> @dosubot[bot] commented on GitHub (Jun 22, 2025): <!-- Greeting --> Hi @SkidGod4444! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> This error happens because Node.js modules like `tls` (used by `mysql2` and thus `drizzle-orm/singlestore`) are only available on the server, not in the browser. If you see this error on the client, it means some server-only code—like your DB config or the `drizzleAdapter`—is being imported into a client-side bundle. To fix this, make sure all database and adapter code (like your `db` and `auth` objects) live in server-only files (for example, in `/lib/server` or `/api`). Only import and use them in API routes, server actions, or other server-side code. On the client, only use client-safe APIs like `createAuthClient` and client plugins. Never import your DB config or `drizzleAdapter` into client components or pages. You can see this separation in the [Better Auth Next.js demo](https://github.com/better-auth/better-auth/blob/2fe1be0e5f023be77b07206dd960f9fd38abba8c/demo/nextjs/app/api/auth/[...all]/route.ts), where server-side auth logic is handled in API routes, and client pages only use client utilities—never the DB or adapter code. If you restructure your code so that server-only modules are never imported on the client, this error will go away. If you need to share types or helpers, put them in separate files that don’t import server-only code. Let me know if you want a concrete example or help reorganizing your files! <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/fdcc7565-a835-49a3-9122-fb86bf0dd376?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/fdcc7565-a835-49a3-9122-fb86bf0dd376?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/fdcc7565-a835-49a3-9122-fb86bf0dd376?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/fdcc7565-a835-49a3-9122-fb86bf0dd376?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/fdcc7565-a835-49a3-9122-fb86bf0dd376?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/fdcc7565-a835-49a3-9122-fb86bf0dd376?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/fdcc7565-a835-49a3-9122-fb86bf0dd376?feedback_type=other)</sup>&nbsp;&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/3136)
Author
Owner

@ping-maxwell commented on GitHub (Jun 22, 2025):

Hey just a few questions to understand your situation better:
Why would authClient have anything to do with tls?
Wouldn't this be a server-side issue if it relates to your DB?

<!-- gh-comment-id:2994391657 --> @ping-maxwell commented on GitHub (Jun 22, 2025): Hey just a few questions to understand your situation better: Why would authClient have anything to do with tls? Wouldn't this be a server-side issue if it relates to your DB?
Author
Owner

@SkidGod4444 commented on GitHub (Jun 22, 2025):

https://github.com/better-auth/better-auth/issues/3136#issuecomment-2994391657 @ping-maxwell

Just FYI to configure auth we need to pass our DB, if you would have noticed the above code. I have something like

database: drizzleAdapter(db, {
        provider: "mysql", // or "pg", "sqlite"
    }),

and this part of the code causing this issue. IDK why.

<!-- gh-comment-id:2994393664 --> @SkidGod4444 commented on GitHub (Jun 22, 2025): https://github.com/better-auth/better-auth/issues/3136#issuecomment-2994391657 @ping-maxwell Just FYI to configure auth we need to pass our DB, if you would have noticed the above code. I have something like ```ts database: drizzleAdapter(db, { provider: "mysql", // or "pg", "sqlite" }), ``` and this part of the code causing this issue. IDK why.
Author
Owner

@Kinfe123 commented on GitHub (Jun 23, 2025):

if you are seeing the error on nextjs client side. it is probably the issue that you are trying to use nodejs native modue that works on server in the client which seems a reasonable thing to check for like the trying to access ttl which is server module on the client side. can you provide a further context on this like authClient instance and how are you actually using it ?

<!-- gh-comment-id:2994608701 --> @Kinfe123 commented on GitHub (Jun 23, 2025): if you are seeing the error on nextjs client side. it is probably the issue that you are trying to use nodejs native modue that works on server in the client which seems a reasonable thing to check for like the trying to access ttl which is server module on the client side. can you provide a further context on this like authClient instance and how are you actually using it ?
Author
Owner

@SkidGod4444 commented on GitHub (Jun 23, 2025):

if you are seeing the error on nextjs client side. it is probably the issue that you are trying to use nodejs native modue that works on server in the client which seems a reasonable thing to check for like the trying to access ttl which is server module on the client side. can you provide a further context on this like authClient instance and how are you actually using it ?

Why would i use a nodejs module on client side? Have you noticed the title of this issue? This is my client side code:

const handleAuth = async (provider: "github" | "discord" | "google") => {
    switch (provider) {
      case "google":
        await authClient.signIn.social({
          provider: provider,
          callbackURL: "/onboarding",
          fetchOptions: {
            onSuccess() {
              console.log("Successfully signed in with Google");
            },
          },
        });
        break;
      case "github":
        await authClient.signIn.social({
          provider: provider,
          callbackURL: "/onboarding",
          fetchOptions: {
            onSuccess() {
              console.log("Successfully signed in with Github");
            },
          },
        });
        break;
      case "discord":
        await authClient.signIn.social({
          provider: provider,
          callbackURL: "/onboarding",
          fetchOptions: {
            onSuccess() {
              console.log("Successfully signed in with Discord");
            },
          },
        });
        break;
      default:
        break;
    }
  };

cc: @ping-maxwell @Kinfe123

<!-- gh-comment-id:2994839239 --> @SkidGod4444 commented on GitHub (Jun 23, 2025): > if you are seeing the error on nextjs client side. it is probably the issue that you are trying to use nodejs native modue that works on server in the client which seems a reasonable thing to check for like the trying to access ttl which is server module on the client side. can you provide a further context on this like authClient instance and how are you actually using it ? Why would i use a nodejs module on client side? Have you noticed the title of this issue? This is my client side code: ```ts const handleAuth = async (provider: "github" | "discord" | "google") => { switch (provider) { case "google": await authClient.signIn.social({ provider: provider, callbackURL: "/onboarding", fetchOptions: { onSuccess() { console.log("Successfully signed in with Google"); }, }, }); break; case "github": await authClient.signIn.social({ provider: provider, callbackURL: "/onboarding", fetchOptions: { onSuccess() { console.log("Successfully signed in with Github"); }, }, }); break; case "discord": await authClient.signIn.social({ provider: provider, callbackURL: "/onboarding", fetchOptions: { onSuccess() { console.log("Successfully signed in with Discord"); }, }, }); break; default: break; } }; ``` cc: @ping-maxwell @Kinfe123
Author
Owner

@Kinfe123 commented on GitHub (Jun 23, 2025):

I'm saying the file that you used being referenced on the client side. But I will try to check by running this and if that is actually the case. Can you share the auth-client as well ?

<!-- gh-comment-id:2994853961 --> @Kinfe123 commented on GitHub (Jun 23, 2025): I'm saying the file that you used being referenced on the client side. But I will try to check by running this and if that is actually the case. Can you share the auth-client as well ?
Author
Owner

@SkidGod4444 commented on GitHub (Jun 25, 2025):

I'm saying the file that you used being referenced on the client side. But I will try to check by running this and if that is actually the case. Can you share the auth-client as well ?

am facing the same issue while using postgress with drizzle ORM.

Module not found: Can't resolve 'fs'

./node_modules/postgres/src/index.js (2:1)

Module not found: Can't resolve 'fs'
  1 | import os from 'os'
> 2 | import fs from 'fs'
    | ^^^^^^^^^^^^^^^^^^^
  3 |
  4 | import {
  5 |   mergeUserTypes,

https://nextjs.org/docs/messages/module-not-found

cc: @Kinfe123 @Bekacru pls help me ASAP!

<!-- gh-comment-id:3003466388 --> @SkidGod4444 commented on GitHub (Jun 25, 2025): > I'm saying the file that you used being referenced on the client side. But I will try to check by running this and if that is actually the case. Can you share the auth-client as well ? am facing the same issue while using postgress with drizzle ORM. ```ts Module not found: Can't resolve 'fs' ./node_modules/postgres/src/index.js (2:1) Module not found: Can't resolve 'fs' 1 | import os from 'os' > 2 | import fs from 'fs' | ^^^^^^^^^^^^^^^^^^^ 3 | 4 | import { 5 | mergeUserTypes, https://nextjs.org/docs/messages/module-not-found ``` cc: @Kinfe123 @Bekacru pls help me ASAP!
Author
Owner

@ping-maxwell commented on GitHub (Jun 25, 2025):

@SkidGod4444 Can you share your auth client code for @Kinfe123 to repro?

<!-- gh-comment-id:3005851569 --> @ping-maxwell commented on GitHub (Jun 25, 2025): @SkidGod4444 Can you share your auth client code for @Kinfe123 to repro?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#9487