"Failed to load external module node:module" when attempting to use middleware with Prisma and Neon serverless
Environment
System:
OS: Linux 6.8 Ubuntu 22.04.5 LTS 22.04.5 LTS (Jammy Jellyfish)
CPU: (8) x64 Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz
Memory: 22.17 GB / 31.28 GB
Container: Yes
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 20.10.0 - ~/.nvm/versions/node/v20.10.0/bin/node
Yarn: 1.22.22 - ~/.nvm/versions/node/v20.10.0/bin/yarn
npm: 10.2.3 - ~/.nvm/versions/node/v20.10.0/bin/npm
pnpm: 9.7.1 - ~/.nvm/versions/node/v20.10.0/bin/pnpm
Browsers:
Chromium: 135.0.7049.84
npmPackages:
@auth/prisma-adapter: ^2.8.0 => 2.8.0
@neondatabase/serverless: ^1.0.0 => 1.0.0
next: 15.3.0 => 15.3.0
next-auth: ^5.0.0-beta.25 => 5.0.0-beta.25
prisma: ^6.6.0 => 6.6.0
react: ^19.0.0 => 19.1.0
Reproduction URL
https://github.com/tremby/auth-test
Describe the issue
I'm trying to get Nextjs, Authjs/next-auth and its middleware, Prisma, and Neon all working together.
I understand that getting databases to work in edge runtimes is tricky, but the docs say that it is supported with various drivers including the Neon serverless one. I'm using Neon, so that sounds OK to me.
The documentation is difficult to follow, since it boots me off to the Prisma site, and also to the Neon site, and each one seems to give slightly different instructions.
I've done my best to follow the instructions. The most straightforward route through the docs which looks to my eye like it ought to be complete is included in the reproduction repo. Step through its commits and see the messages for details. Not included in the reproduction repo, I also tried various different versions and combinations of the instructions, anything I could find.
With every iteration, when running npm run dev and navigating to localhost:3000 I see a stack trace, and in the console I have a lot of these:
⨯ [Error: Failed to load external module node:module: ReferenceError: Cannot access 'require' before initialization]
How to reproduce
- Check out the reproduction repo
npm installcp .env.example .envvim .envand fill in valuesnpx prisma generatenpm run dev- Navigate to
localhost:3000 - See stack trace and console output
Expected behavior
Middleware executes successfully. Page loads. No errors.
+1 - similar behaviour with Prisma and local Postgres.
Followed this guide to setup Prisma: https://www.prisma.io/docs/getting-started/setup-prisma/add-to-existing-project/relational-databases-typescript-postgresql
Followed this guide for Auth.js + Prisma configuration: https://authjs.dev/getting-started/adapters/prisma
Hope this helps!
+1 - similar behaviour with Prisma and local Postgres. ... Hope this helps!
I find it unclear from your message whether you have it working or not.
I'm trying to use Neon Serverless, which Prisma's docs say is one of the database drivers which is edge-compatible (and therefore hopefully middleware-compatible). Which driver are you using?
+1 - similar behaviour with Prisma and local Postgres.
I find it unclear from your message whether you have it working or not.
Apologies for the confusion - to clarify, I am facing the same issue as yourself and I do not have a working fix as yet.
Running into the same issue but standalone. Not serverless. Everything was running fine and then added the middleware and boom.
Prisma Postgres "next-auth": "^5.0.0-beta.25",
Barebones middleware.ts
export { auth as middleware } from "@/lib/auth"
Stack trace.
Error: Failed to load external module node:module: ReferenceError: Cannot access 'require' before initialization
at Object.externalRequire [as x] (file:///Users/marty/develop/BookChequer/bookchequer-web/.next/server/edge/chunks/edge-wrapper_effe2de8.js:1448:15)
at [project]/node_modules/@prisma/client/runtime/library.mjs [middleware-edge] (ecmascript) (file:///Users/marty/develop/BookChequer/bookchequer-web/.next/server/edge/chunks/node_modules_@prisma_client_e24b49d2._.js:41:74)
at <unknown> (file:///Users/marty/develop/BookChequer/bookchequer-web/.next/server/edge/chunks/edge-wrapper_effe2de8.js:722:27)
at runModuleExecutionHooks (file:///Users/marty/develop/BookChequer/bookchequer-web/.next/server/edge/chunks/edge-wrapper_effe2de8.js:768:9)
at instantiateModule (file:///Users/marty/develop/BookChequer/bookchequer-web/.next/server/edge/chunks/edge-wrapper_effe2de8.js:720:9)
at getOrInstantiateModuleFromParent (file:///Users/marty/develop/BookChequer/bookchequer-web/.next/server/edge/chunks/edge-wrapper_effe2de8.js:653:12)
at esmImport (file:///Users/marty/develop/BookChequer/bookchequer-web/.next/server/edge/chunks/edge-wrapper_effe2de8.js:143:20)
at [project]/node_modules/@auth/prisma-adapter/index.js [middleware-edge] (ecmascript) (file:///Users/marty/develop/BookChequer/bookchequer-web/.next/server/edge/chunks/node_modules_99b3511c._.js:4281:191)
at <unknown> (file:///Users/marty/develop/BookChequer/bookchequer-web/.next/server/edge/chunks/edge-wrapper_effe2de8.js:722:27)
at runModuleExecutionHooks (file:///Users/marty/develop/BookChequer/bookchequer-web/.next/server/edge/chunks/edge-wrapper_effe2de8.js:768:9)
I got the same issue as you.
System:
OS: Linux 5.15 Ubuntu 24.04.2 LTS 24.04.2 LTS (Noble Numbat)
CPU: (12) x64 Intel(R) Core(TM) i7-7800X CPU @ 3.50GHz
Memory: 8.32 GB / 15.47 GB
Container: Yes
Shell: 5.9 - /usr/bin/zsh
Binaries:
Node: 22.12.0 - ~/.nvm/versions/node/v22.12.0/bin/node
Yarn: 1.22.22 - ~/.nvm/versions/node/v22.12.0/bin/yarn
npm: 10.9.0 - ~/.nvm/versions/node/v22.12.0/bin/npm
pnpm: 10.6.1 - ~/.local/share/pnpm/pnpm
Browsers:
Chrome: 135.0.7049.52
npmPackages:
@auth/prisma-adapter: ^2.8.0 => 2.8.0
next: 15.3.1 => 15.3.1
next-auth: ^5.0.0-beta.25 => 5.0.0-beta.25
react: ^19.0.0 => 19.1.0
I am not using Neon at all but got the same error using basic install process.
Object.externalRequire [as x]
[turbopack]/shared-node/base-externals-utils.ts (41:11)
[project]/node_modules/@prisma/client/runtime/library.mjs [middleware-edge] (ecmascript)
node_modules/@prisma/client/runtime/library.mjs (1:1)
<unknown>
[turbopack]/browser/runtime/base/dev-base.ts (201:21)
runModuleExecutionHooks
[turbopack]/browser/runtime/base/dev-base.ts (261:5)
instantiateModule
[turbopack]/browser/runtime/base/dev-base.ts (199:5)
getOrInstantiateModuleFromParent
[turbopack]/browser/runtime/base/dev-base.ts (128:10)
esmImport
[turbopack]/shared/runtime-utils.ts (214:18)
[project]/node_modules/@auth/prisma-adapter/index.js [middleware-edge] (ecmascript)
node_modules/@auth/prisma-adapter/index.js (1:1)
<unknown>
[turbopack]/browser/runtime/base/dev-base.ts (201:21)
runModuleExecutionHooks
[turbopack]/browser/runtime/base/dev-base.ts (261:5)
I am having the same error with a similar stack :
The problem has been resolved.
follow this guide: Neon Edge Compatibility
// auth.ts
// This file is responsible for setting up authentication using NextAuth.js and Prisma.
import NextAuth from "next-auth";
import { PrismaAdapter } from "@auth/prisma-adapter";
import authConfig from "./auth.config";
import prisma from "@/lib/prisma";
export const { handlers, signIn, signOut, auth } = NextAuth({
adapter: PrismaAdapter(prisma),
session: {
strategy: "jwt",
},
...authConfig,
});
// auth.config.ts
// This file is responsible for configuring authentication providers and settings.
import type { NextAuthConfig } from "next-auth";
import Google from "next-auth/providers/google";
export default { providers: [Google] } satisfies NextAuthConfig;
// prisma.ts
// This file is responsible for setting up the Prisma client and database connection.
import { neonConfig } from "@neondatabase/serverless";
import { PrismaClient } from "@prisma/client";
import ws from "ws";
declare global {
// eslint-disable-next-line no-var
var prisma: PrismaClient | undefined;
}
const connectionString = `${process.env.DATABASE_URL}`;
neonConfig.webSocketConstructor = ws;
const prisma =
global.prisma ||
new PrismaClient({ datasources: { db: { url: connectionString } } });
export default prisma;
if (process.env.NODE_ENV === "development") global.prisma = prisma;
@gmsetiawan, I tried using your example code above and I still see the same error.
I committed that to a branch of my test repo: https://github.com/tremby/auth-test/tree/gmsetiawan
If you'd be so kind, please check that out and let me know what I've missed.
@tremby
Try it
// middleware.ts
// This file is used to configure NextAuth.js middleware
// and protect routes in the application.
import authConfig from "./auth.config";
import NextAuth from "next-auth";
export const { auth: middleware } = NextAuth(authConfig);
Everything running as you want.
It's working for me now. Thank you.
Using both password and google login.
Same issue here. Using PlanetScale, Turbopack and experimental Node middleware.
next: 15.3.1-canary.15
next-auth: 5.0.0-beta.26
@auth/core: 0.39.0
@auth/prisma-adapter: 2.9.0
Runtime Error
Error: Failed to load external module node:module: ReferenceError: Cannot access 'require' before initialization
Object.externalRequire [as x]
.next\server\edge\chunks\apps_main_edge-wrapper_97cb0bdf.js (1448:15)
[project]/node_modules/@prisma/client/runtime/library.mjs [middleware-edge] (ecmascript)
.next\server\edge\chunks\node_modules_@prisma_client_2a1680e0._.js (41:74)
<unknown>
.next\server\edge\chunks\apps_main_edge-wrapper_97cb0bdf.js (722:27)
runModuleExecutionHooks
.next\server\edge\chunks\apps_main_edge-wrapper_97cb0bdf.js (768:9)
instantiateModule
.next\server\edge\chunks\apps_main_edge-wrapper_97cb0bdf.js (720:9)
getOrInstantiateModuleFromParent
.next\server\edge\chunks\apps_main_edge-wrapper_97cb0bdf.js (653:12)
esmImport
.next\server\edge\chunks\apps_main_edge-wrapper_97cb0bdf.js (143:20)
[project]/node_modules/@auth/prisma-adapter/index.js [middleware-edge] (ecmascript)
.next\server\edge\chunks\node_modules_fb4e896c._.js (4247:191)
<unknown>
.next\server\edge\chunks\apps_main_edge-wrapper_97cb0bdf.js (722:27)
runModuleExecutionHooks
.next\server\edge\chunks\apps_main_edge-wrapper_97cb0bdf.js (768:9)
Same problem here when using Next.JS Prisma and Local PostgreSQL. Disable Turbopack helps but didn't solve the problem. Any workaround?
I'm using @auth/prisma-adapter v2.7.4 to make it work
@gmsetiawan
Try it
// middleware.ts // This file is used to configure NextAuth.js middleware // and protect routes in the application. import authConfig from "./auth.config"; import NextAuth from "next-auth"; export const { auth: middleware } = NextAuth(authConfig);Everything running as you want.
OK, I made that change, and it's no longer erroring. It appears to also work without forcing the session stategy to JWT.
But if I understand correctly what this is doing, it's not actually connecting to the database at all. In the middleware file you have it passing configuration to NextAuth which doesn't include the database adapter at all. And I think that'll mean that if I'm not using the JWT strategy, then the middleware's purpose, to refresh tokens, isn't going to be achieved.
@eduardochiaro
I'm using
@auth/prisma-adapterv2.7.4 to make it work
Interesting.
I just tried this and that does get me past that error. But now it's complaining that it doesn't have the connection string. It seems middleware doesn't load environment variables. If I try to manually load them, whether with @next/env or dotenv, I get an error saying that process.cwd isn't supported in the edge runtime environment.
Can you tell us how you got around that, please?
Can confirm that rolling back to @auth/prisma-adapter 2.7.4 resolved my issue (I'm using prisma + postgres)
For me I rolled back @auth/prisma-adapter for 2.7.4 But that alone didn't solve it, I had to add the runtime configuration for nodejs
In next.config.ts
experimental: { nodeMiddleware: true, },
And in middleware file
export const config = { runtime: 'nodejs', }
This worked for me
Some links that helped me NextJS, Auth.js and Postgres. Any way to make this combo work? Next.js runtime config
This can be resolved by using two different config for middleware and other things because in next js middleware runs on edge runtime which will not support adapters that we use because database are not compatible running on edge so we segregate config in two parts as below and use config that doesn't contain adapter in middleware.
// auth.config.ts
import GitHub from "next-auth/providers/github";
import type { NextAuthConfig } from "next-auth";
import Google from "next-auth/providers/google";
// Notice this is only an object, not a full Auth.js instance
export default {
providers: [GitHub, Google],
} satisfies NextAuthConfig;
// middleware.ts
import NextAuth from "next-auth";
import authConfig from "./auth.config";
export const { auth: middleware } = NextAuth(authConfig);
Finally for normal use cases other than middleware
// auth.ts
import NextAuth from "next-auth";
import authConfig from "./auth.config";
import { PrismaClient } from "@prisma/client";
import { PrismaAdapter } from "@auth/prisma-adapter";
const prisma = new PrismaClient();
export const { handlers, auth, signIn, signOut } = NextAuth({
adapter: PrismaAdapter(prisma),
session: { strategy: "jwt" },
...authConfig,
});
Thank you!
Downgrading to @auth/prisma-adapter 2.7.2 should solve it. There is an open issue for this, see https://github.com/nextauthjs/next-auth/issues/12731
What worked for me was the downgrade @auth/prisma-adapter to 2.7.4. but I needed to do a lot of changes to turn Prisma able to work with auth middleware with any errors, main was to separate AuthOptions and in this ways:
//authServer.ts
import NextAuth from "next-auth";
import { PrismaAdapter } from "@auth/prisma-adapter";
import db from "@/lib/db/db";
import { authOptions } from "./authOptions";
export const { handlers, signIn, signOut, auth } = NextAuth({
...authOptions,
adapter: PrismaAdapter(db),
});
//middleware.ts
import { authOptions } from '@/lib/auth/authOptions';
import NextAuth, { NextAuthConfig } from "next-auth";
import { NextResponse } from "next/server";
// Middleware auth WITHOUT Prisma
const { auth } = NextAuth(authOptions)
export default async function middleware(req: Request) {
const session = await auth(req as any);
if (!session) {
return NextResponse.redirect(new URL("/auth/signin", req.url));
}
return NextResponse.next();
}
export const config = {
matcher: ["/xxx/:path*"],
};
and
// authOptions.ts
import { NextAuthConfig } from "next-auth";
import Google from "next-auth/providers/google";
export const authOptions = {
providers: [Google],
secret: process.env.AUTH_SECRET,
session: {
strategy: "jwt", // ---> this line was important to avoid errors
},
// Important: keep all callbacks & configs that affects the session
} as NextAuthConfig;
Maybe somethings was specific because I try external credentials and use MongoDB as database.
+1
Edit by maintainer bot: Comment was automatically minimized because it was considered unhelpful. (If you think this was by mistake, let us know). Please only comment if it adds context to the issue. If you want to express that you have the same problem, use the upvote 👍 on the issue description or subscribe to the issue for updates. Thanks!
Downgrading prisma-adapter version to 2.7.4 solves it.