Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Doesn't work with next.js Edge runtime #3206

Open
etodanik opened this issue May 2, 2024 · 36 comments
Open

Doesn't work with next.js Edge runtime #3206

etodanik opened this issue May 2, 2024 · 36 comments

Comments

@etodanik
Copy link

etodanik commented May 2, 2024

I'm writing an app on next.js which I plan to deploy to CloudFlare Pages + Workers. I know there's CloudFlare support, but when running the local development server of next.js, I get the following errors:

Learn More: https://nextjs.org/docs/messages/node-module-in-edge-runtime
    at <unknown> (webpack-internal:///(middleware)/./node_modules/next/dist/esm/server/web/globals.js:33)
    at Object.get (webpack-internal:///(middleware)/./node_modules/next/dist/esm/server/web/globals.js:33:19)
    at eval (webpack-internal:///(middleware)/./node_modules/pg/lib/crypto/utils-webcrypto.js:19:36)
    at (middleware)/./node_modules/pg/lib/crypto/utils-webcrypto.js (file:///home/danny/src/project/.next/server/pages/api/manageUser.js:3097:1)
    at __webpack_require__ (file:///home/danny/src/project/.next/server/edge-runtime-webpack.js:37:33)
    at fn (file:///home/danny/src/project/.next/server/edge-runtime-webpack.js:286:21)
    at eval (webpack-internal:///(middleware)/./node_modules/pg/lib/crypto/utils.js:7:22)
    at (middleware)/./node_modules/pg/lib/crypto/utils.js (file:///home/danny/src/project/.next/server/pages/api/manageUser.js:3108:1)
    at __webpack_require__ (file:///home/danny/src/project/.next/server/edge-runtime-webpack.js:37:33)
    at fn (file:///home/danny/src/project/.next/server/edge-runtime-webpack.js:286:21)
    at eval (webpack-internal:///(middleware)/./node_modules/pg/lib/crypto/sasl.js:3:16)

Would it make sense to generalize CloudFlare Workers detection into a broader Edge detection that also includes node edge runtime?

@brianc
Copy link
Owner

brianc commented May 2, 2024

Yeah it would probably...how does one reproduce this issue locally? If running in node then pg should be using the node pieces.

@etodanik
Copy link
Author

etodanik commented May 2, 2024

Set up a basic next.js app, create an API endpoint, set its' runtime to edge by specifying:
export const runtime = 'edge';

And then assume to use node-postgres from within that route.

CloudFlare Pages requires a next.js app to specify that all backend endpoints will be using the edge runtime.

There's a further complication that NodeEdge runtime isn't the same as CloudFlare workers. I suppose next.js' NodeEdge is emulating what Vercel's edge runtime would look like. But one important detail is that it won't have the ability to run cloudflare:sockets

@muhammedaksam
Copy link

I am trying to use Prisma, PrismaPg and Pg.

Error: The edge runtime does not support Node.js 'crypto' module.

Call Stack

Next.js
eval
node_modules\.pnpm\[email protected]\node_modules\pg\lib\crypto\utils-webcrypto.js (21:1)
(middleware)/./node_modules/.pnpm/[email protected]/node_modules/pg/lib/crypto/utils-webcrypto.js
file:///C:/Code/React/nextplate/.next/server/middleware.js (1292:1)
Next.js
eval
node_modules\.pnpm\[email protected]\node_modules\pg\lib\crypto\utils.js (8:3)
(middleware)/./node_modules/.pnpm/[email protected]/node_modules/pg/lib/crypto/utils.js
file:///C:/Code/React/nextplate/.next/server/middleware.js (1303:1)
Next.js
eval
node_modules\.pnpm\[email protected]\node_modules\pg\lib\crypto\sasl.js (2:16)

https://vercel.com/docs/functions/runtimes/edge-runtime#unsupported-apis

I know it's not really an issue related to Pg but I wanted to inform here anyway.

@mlntr
Copy link

mlntr commented May 19, 2024

I am using Next.js and Drizzle, and get the same: Error: The edge runtime does not support Node.js 'crypto' module. Learn More: https://nextjs.org/docs/messages/node-module-in-edge-runtime

@andyjy
Copy link

andyjy commented May 28, 2024

This patch fixes for me. Specifically: prevents the error Error: The edge runtime does not support Node.js 'crypto' module. when using pg under the Next.js Edge runtime locally.

pg+8.11.5.patch:

diff --git a/node_modules/pg/lib/crypto/utils-webcrypto.js b/node_modules/pg/lib/crypto/utils-webcrypto.js
index 0433f01..588066e 100644
--- a/node_modules/pg/lib/crypto/utils-webcrypto.js
+++ b/node_modules/pg/lib/crypto/utils-webcrypto.js
@@ -13,7 +13,10 @@ module.exports = {
  * The Web Crypto API - grabbed from the Node.js library or the global
  * @type Crypto
  */
-const webCrypto = nodeCrypto.webcrypto || globalThis.crypto
+
+// PATCH: Don't break under Next.js Edge runtime production build
+const webCrypto = ("webcrypto" in nodeCrypto ? nodeCrypto.webcrypto : undefined) ?? globalThis.crypto
+
 /**
  * The SubtleCrypto API for low level crypto operations.
  * @type SubtleCrypto

(I opted to use runtime-agnostic Feature Detection for webcrypto on the crypto import rather than try detect the Next.js Edge runtime specifically via typeof EdgeRuntime === "string", which I assume could be a valid alternative - haven't verified)

@janpio
Copy link
Contributor

janpio commented Jun 5, 2024

Quick note from @prisma that this affects some of our users and is being reported to us: prisma/prisma#24430

(This issue has a reproduction, but that includes Prisma, Next.js and next-auth - that is probably a bit more than what you are asking for @brianc. I am pretty sure just trying to use pg in a Next.js middleware should have the same result though.)

We would love to see this fixed and released, so that Prisma users wanting to use pg in Next.js projects with middleware can do so. Let us know if we can help in any way.

@brianc
Copy link
Owner

brianc commented Jun 5, 2024

k i'll get this looked at today if I have time!

@brianc
Copy link
Owner

brianc commented Jun 5, 2024

@janpio @andyjy @etodanik would one of y'all be able to provide me w/ more concrete steps to follow to set up a local reproduction? I did npx create-next-app@latest and did NOT use the API router (so the legacy or older form of nextjs). It created a hello api route:

image

So i tested it at http://localhost:3000/api/hello and it worked. great. then I went into the route file and added

export const runtime = 'edge'

and now its erroring when I hit the route:

image

So I'm doing something wrong, but not sure what.

This is the full contents of my hello.ts api route file:

// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from "next";

type Data = {
  name: string;
};

export const runtime = 'edge'

export default function handler(
  req: NextApiRequest,
  res: NextApiResponse<Data>,
) {
  res.status(200).json({ name: "John Doe" });
}

@brianc
Copy link
Owner

brianc commented Jun 5, 2024

update: I tried a different next-js app using the app router instead of the old pages/* approach

I just did same steps as above except said "yes" when the setup asked me to use an app router.

Setup looks like this:

image

my route.ts file:

import * as pg from 'pg'

export const runtime = 'edge'
const pool = new pg.Pool()

export async function GET() {
  const { rows } = await pool.query('SELECT 1 as one')

  return Response.json({ rows })
}

Immediately when I run 'yarn next dev' to start the project it errors out with being unable to import pg-native which is annoying....I've never messed w/ the edge runtime before - it's quite a bit different...so any thoughts on this?


Import trace for requested module:
./node_modules/pg/lib/connection-parameters.js
./node_modules/pg/lib/client.js
./node_modules/pg/lib/index.js
./src/app/api/route.ts
./node_modules/next/dist/build/webpack/loaders/next-edge-app-route-loader/index.js?absolutePagePath=%2FUsers%2Fbmc%2Fsrc%2Fpg-edge-test%2Fsrc%2Fapp%2Fapi%2Froute.ts&page=%2Fapi%2Froute&appDirLoader=bmV4dC1hcHAtbG9hZGVyP25hbWU9YXBwJTJGYXBpJTJGcm91dGUmcGFnZT0lMkZhcGklMkZyb3V0ZSZhcHBQYXRocz0mcGFnZVBhdGg9cHJpdmF0ZS1uZXh0LWFwcC1kaXIlMkZhcGklMkZyb3V0ZS50cyZhcHBEaXI9JTJGVXNlcnMlMkZibWMlMkZzcmMlMkZwZy1lZGdlLXRlc3QlMkZzcmMlMkZhcHAmcGFnZUV4dGVuc2lvbnM9dHN4JnBhZ2VFeHRlbnNpb25zPXRzJnBhZ2VFeHRlbnNpb25zPWpzeCZwYWdlRXh0ZW5zaW9ucz1qcyZyb290RGlyPSUyRlVzZXJzJTJGYm1jJTJGc3JjJTJGcGctZWRnZS10ZXN0JmlzRGV2PXRydWUmdHNjb25maWdQYXRoPXRzY29uZmlnLmpzb24mYmFzZVBhdGg9JmFzc2V0UHJlZml4PSZuZXh0Q29uZmlnT3V0cHV0PSZwcmVmZXJyZWRSZWdpb249Jm1pZGRsZXdhcmVDb25maWc9ZTMwJTNEIQ%3D%3D&nextConfigOutput=&preferredRegion=&middlewareConfig=e30%3D!
 ○ Compiling /api ...
 ⚠ ./node_modules/pg/lib/native/client.js
Module not found: Can't resolve 'pg-native' in '/Users/bmc/src/pg-edge-test/node_modules/pg/lib/native'

I know its trying to webpack the server...which is fun.

@andyjy
Copy link

andyjy commented Jun 5, 2024

@brianc here you go - reproduction for pages router:
https://github.com/andyjy/mre-pg-nextjs-edge

@brianc
Copy link
Owner

brianc commented Jun 5, 2024

here you go - reproduction for pages router:

amazing, ty

@brianc
Copy link
Owner

brianc commented Jun 5, 2024

@andyjy when i applied your patch to the crypto file I now get this:

⨯ Error: The edge runtime does not support Node.js 'net' module.
Learn More: https://nextjs.org/docs/messages/node-module-in-edge-runtime
    at Object.construct (webpack-internal:///(middleware)/./node_modules/next/dist/esm/server/web/globals.js:37:19)
    at getStream (webpack-internal:///(middleware)/./node_modules/pg/lib/stream.js:8:12)
    at new Connection (webpack-internal:///(middleware)/./node_modules/pg/lib/connection.js:19:36)
    at new Client (webpack-internal:///(middleware)/./node_modules/pg/lib/client.js:48:7)
    at handler (webpack-internal:///(middleware)/./src/pages/api/hello.ts:13:16)
    at eval (webpack-internal:///(middleware)/./node_modules/next/dist/esm/server/api-utils/index.js:32:16)
    at eval (webpack-internal:///(middleware)/./node_modules/next/dist/esm/server/lib/trace/tracer.js:115:36)
    at NoopContextManager.with (webpack-internal:///(middleware)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:2:7062)
    at ContextAPI.with (webpack-internal:///(middleware)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:2:518)
    at NoopTracer.startActiveSpan (webpack-internal:///(middleware)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:2:18108)
 ✓ Compiled in 107ms (263 modules)

@andyjy
Copy link

andyjy commented Jun 5, 2024

@andyjy when i applied your patch to the crypto file I now get this:

ah ok, turns out I am using import { Pool } from "pg" in my app, which the patch above solves for - whereas in the reproduction repo I happened to write import { Client } from "pg" which exposes the new net incompatibility.

Update: 🤦‍♂️ sorry, I realised that while the patch I shared above indeed prevents the Next.js local edge runtime compilation error, I'm not actually executing the pg Client under the Edge runtime locally. So the patch only fixes import, not usage.. (yes I know, facepalm..)

(I remembered I'm actually serving my API routes that use pg under the Node runtime, although my code that references pg is imported - albeit never executed - within some of my Edge runtime routes, which is why I produced the patch.)

Sorry for the incorrect/misleading post previously!

Thinking ahead to whether/how it's possible to get things actually working under the Next.js Edge runtime locally - it would probably(?) require breaking out of Next.js' local Edge Runtime "sandbox" to access node:net locally (i.e. via the Next.js Webpack config). So if this is the case, some tweaks to pg may be necessary but not sufficient alone.

If I get an actually-working prototype then I'll share back.

@janpio
Copy link
Contributor

janpio commented Jun 5, 2024

Tiny PR to @andyjy's repro to show the same problem with a Next.js middleware, the common case where Prisma users run into this: andyjy/mre-pg-nextjs-edge#1

Thinking ahead to whether/how it's possible to get things actually working under the Next.js Edge runtime locally - it would probably(?) require breaking out of Next.js' local Edge Runtime "sandbox" to access node:net locally (i.e. via the Next.js Webpack config). So if this is the case, some tweaks to pg may be necessary but not sufficient alone.

Semi informed comment from the sidelines: Afaik the Cloudflare Workers support for pg had similar challenges, that parts of the internal pg code had to be disabled or skipped to not use APIs that are not available in the CfW environment.

@brianc
Copy link
Owner

brianc commented Jun 5, 2024

Sorry for the incorrect/misleading post previously!

absolutely no problem! I'll continue to noodle on this....might take a bit of time to do a similar retrofit that the CF stuff did. I'm also about to go out of town for a bit so...hang tight - i'll get there eventually!

@janpio
Copy link
Contributor

janpio commented Jun 6, 2024

🤔
Can node-postgres even work in the edge runtime by Vercel and Next.js? Isn't it missing TCP socket support, and Vercel does not offer a connect() like Cloudflare does, that could be used instead. That would be a limitation of Next.js functionality that uses the edge runtime (middleware, app routes) to not be able to support pg at all.

@andyjy
Copy link

andyjy commented Jun 6, 2024

🤔 Can node-postgres even work in the edge runtime by Vercel and Next.js? Isn't it missing TCP socket support, and Vercel does not offer a connect() like Cloudflare does, that could be used instead. That would be a limitation of Next.js functionality that uses the edge runtime (middleware, app routes) to not be able to support pg at all.

Yes - having looked into it more, I also realised you're essentially correct - that lack of TCP socket support is a blocker for the Next.js/Vercel Edge Runtime.

Despite running on Cloudflare Workers behind the scenes (still ?) - when deploying to Vercel, Edge runtime code that references require("cloudflare:sockets") fails to deploy, with error The Edge Function "middleware" is referencing unsupported modules: cloudflare:sockets.

What I assume is possible is deploying a Next.js app using the Edge runtime directly to Cloudflare. With no Vercel / Edge Runtime wrapper, the bundled code should just work on Cloudflare Workers.

And if someone wishes to do that, it is technically possible to:

  1. Patch pg to compile/bundle successfully under Next.js' Webpack config. This requires a bunch of patching.. and additional next.config.js config.

  2. Patch Next.js to successfully pg under the Edge runtime (middleware, Pages API routes + App router) under local development (next dev), by breaking through the local Edge sandbox to expose net.Socket(!). Requires a patch and additional next.config.js config.

Potentially handy if anyone really wants to develop using Next.js + pg under Edge before deploying to Cloudflare.. but I can't imagine this ever being supported by Next.js "officially" unless the Edge runtime is somehow updated to incorporate TCP socket support...(!?)

The reproduction repo is now updated with a proof of concept for both (1) and (2). I haven't deployed to Cloudflare directly but see no reason why this wouldn't work (potentially with a bit more tweaking to get the output bundle correct)

/nerd-snipe over

@janpio
Copy link
Contributor

janpio commented Jun 6, 2024

Thanks for the validation of my thought, I was not sure if I was really mixing things up now.

Note, that will probably make this a lot more confusing instead of helping, as it makes it more complex: For Cloudflare Pages there is an additional package next-on-pages so one can deploy Next.js to Cloudflare Pages, and that has its own problem with pg: cloudflare/next-on-pages#605 Not sure if the "Edge Runtime" (from Next.js and Vercel) is even involved there anymore though.

Probably means no easy way to use pg in Next.js middlewares though 😢

@andyjy
Copy link

andyjy commented Jun 6, 2024

@janpio here's the reproduction repo deployed directly to cloudflare via @cloudflare/next-on-pages

.. it works(!) - connecting to a Neon database using node-postgres:

The (currently super ugly..) patches to pg I mentioned above are what fixes cloudflare/next-on-pages#605

🎉

@andyjy
Copy link

andyjy commented Jun 6, 2024

@janpio ..and here it is deployed to Cloudflare with Prisma added (via @prisma/adapter-pg):

Pages router API route: https://d2ff1a42.mre-pg-nextjs-edge.pages.dev/api/hello-app
App router: https://d2ff1a42.mre-pg-nextjs-edge.pages.dev/api/hello-app
Edge middleware: https://d2ff1a42.mre-pg-nextjs-edge.pages.dev/api/foo

@janpio
Copy link
Contributor

janpio commented Jun 7, 2024

Ok wow, that is pretty wild @andyjy - amazing!

Do I understand correctly that you seem a way to make pg work on Cloudflare Pages via next-on-pages via some changes?
But deploying to Vercel is still completely out of the picture, correct?

@andyjy
Copy link

andyjy commented Jun 7, 2024

Do I understand correctly that you seem a way to make pg work on Cloudflare Pages via next-on-pages via some changes

Exactly! And specifically those changes are:

  1. Patch pg to compile/bundle successfully under Next.js' Webpack config. This requires a bunch of patching.. and additional next.config.js config.

I believe this fixes cloudflare/next-on-pages#605

(The patches linked above are still a bit of a messy proof-of-concept - in particular there are some "unhappy paths" in pg that execute during handling of e.g. connection errors/exceptions that use other unsupported Node APIs e.g. process.nextTick(), that I believe will crash currently, but could probably(?) be switched out for the cross-platform queueMicrotask()(?).

The changes in my patches would also need a bit more love before they can be merged into pg in a clean way and without breaking anything for non-Edge runtimes and non-Next.js bundler configs. Should be very doable but I expect quite a chore unfortunately..)

Re: Vercel:

But deploying to Vercel is still completely out of the picture, correct

Yes - at least, I observe that when pushing bundled code to Vercel that includes require("cloudflare:sockets"), Vercel's deployment process objects with error The Edge Function "...." is referencing unsupported modules: cloudflare:sockets

(It's the same error if I push any code referencing e.g. require("this_module_does_not_exist"))

As I understand it - Vercel's Edge runtime product specifically supports their Edge Runtime API that is designed to be runnable under various V8-powered environments - AFAIK they don't particualrly publicise the fact it's Cloudflare Workers under the hood (and could host their Vercel Edge functions elsewhere under non-Cloudflare at any time - for all I know they may do already!).

So at this point while it may be worth asking a friendly contact at Vercel about the possibility of bypassing the unsupported module: cloudflare:sockets error and running this code on Vercel, even if there is some way to make it work today I still wouldn't be too optimistic about it not breaking in future. The only practical way I can imagine would be if Vercel add support for a TCP socket library to their official Edge Runtime spec.

@janpio
Copy link
Contributor

janpio commented Jun 7, 2024

Shared that workaround over at next-on-pages: cloudflare/next-on-pages#605 (comment)

@brianc
Copy link
Owner

brianc commented Jun 18, 2024

Hi! I'm back from my trip - will be looking into this tomorrow morning! Thanks for all the help & research...I'll dive in tomorrow with some 👀 and 🔨

@brianc
Copy link
Owner

brianc commented Jun 19, 2024

ugg...reading up on the edge runtime vm trying to come up w/ a way to write some test for this within the repo. A bit complicated. Definitely open to ideas & help on this or a PR w/ the patch (though yeah I looked at it, it needs a bit more massaging). Thanks for the work so far @andyjy!

@andresgutgon
Copy link

Same issues here using Drizzle with node-postgres and next-auth which use as DB adapter drizzle/pg. What I did is to do a dummy next-auth adapter stripping DB

import { AUTH_MAX_AGE } from '$/auth/constants';
import Google from 'next-auth/providers/google'
import NextAuth from 'next-auth'
import { NextResponse } from 'next/server';
import { NextAuthRequest } from 'node_modules/next-auth/lib';

// Make here the dummny next-auth without PostgreSQL dependency
const { auth } = NextAuth({
  session: { strategy: 'jwt', maxAge: AUTH_MAX_AGE },
  providers: [Google]
})

export default auth((_req: NextAuthRequest) => {
  return NextResponse.next();
})

export const config = {
  matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
}

Not sure if this works but at least in development the page load

@muhammedaksam
Copy link

muhammedaksam commented Jun 29, 2024

Same issues here using Drizzle with node-postgres and next-auth which use as DB adapter drizzle/pg. What I did is to do a dummy next-auth adapter stripping DB

import { AUTH_MAX_AGE } from '$/auth/constants';
import Google from 'next-auth/providers/google'
import NextAuth from 'next-auth'
import { NextResponse } from 'next/server';
import { NextAuthRequest } from 'node_modules/next-auth/lib';

// Make here the dummny next-auth without PostgreSQL dependency
const { auth } = NextAuth({
  session: { strategy: 'jwt', maxAge: AUTH_MAX_AGE },
  providers: [Google]
})

export default auth((_req: NextAuthRequest) => {
  return NextResponse.next();
})

export const config = {
  matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
}

Not sure if this works but at least in development the page load

If you are going to use JWT as strategy you probably don't need to use an adapter for your Next Auth so you probably don't need to use Pg either.

@andresgutgon
Copy link

If you are going to use JWT as strategy you probably don't need to use an adapter for your Next Auth so you probably don't need to use Pg either.

I still need to use PG adapter for storing users and accounts

@vnce
Copy link

vnce commented Jun 30, 2024

For those hitting this issue as part of a next-auth / auth js 5 integration, this document helped me understand the situation better: https://authjs.dev/guides/edge-compatibility

"""
PostgreSQL is a database that uses a message-based protocol for communication between a the client and server that is transported via TCP (or Unix) sockets. Raw TCP sockets are one of those Node.js features that are generally not available to edge runtimes. Therefore, on the surface, it seems like it’s not possible to communicate with a PostgreSQL database from JavaScript running on edge runtime. The same goes for many other databases and their respective communication protocols.

As edge runtimes have matured and become more popular, however, people have gotten creative and implemented various solutions to this problem. One such common solution is to put some sort of API server in front of the database whose goal is to translate database queries sent to it via HTTP into a protocol the database can understand. This allows the client side to only have to make HTTP requests to the API server, which is something that every edge runtime supports.
"""

My workaround was to expose an API to pg that an auth.ts callback can hit from edge. I think I'd still prefer using pg in edge runtime (sounds like Brian is close to a solution), but maybe this is working as intended if node-postgres is designed for the node.js runtime, which Vercel's Edge runtime doesn't (or only partially) uses

@andresgutgon
Copy link

My workaround was to expose an API to pg that an auth.ts callback can hit from edge. I think I'd still prefer using pg in edge runtime (sounds like Brian is close to a solution), but maybe this is working as intended if node-postgres is designed for the node.js runtime, which Vercel's Edge runtime doesn't (or only partially) uses

But you still can have middleware if you use jwt and node-postgresql. This worked for me and is explained in the docs here

@Goldziher
Copy link

This is sufficent:

import { MiddlewareConfig, NextResponse } from "next/server";
import { PagePath } from "@/enums";
import NextAuth from "next-auth";

const { auth } = NextAuth({ providers: [] });

export const middleware = auth(async (req) => {
	const path = new URL(req.url).pathname;

	const session = await auth();

	const isSigninPage = path === PagePath.SIGNIN.toString();
	const isRootPage = path === PagePath.ROOT.toString();
	const isAPIRoute = path.startsWith("/api");

	if (session && isSigninPage) {
		return NextResponse.redirect(new URL(PagePath.ROOT, req.url));
	}

	if (!session && !(isRootPage || isSigninPage || isAPIRoute)) {
		return NextResponse.redirect(new URL(PagePath.SIGNIN, req.url));
	}
});

export const config: MiddlewareConfig = {
	matcher: ["/((?!api|_next/static|_next/image\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)"],
};

BUT you have to ensure that you are using the JWT strategy and never access the DB during the middleware, here is auth.ts:

import NextAuth, { DefaultSession } from "next-auth";
import { DrizzleAdapter } from "@auth/drizzle-adapter";
import { getDatabaseClient } from "db/connection";
import { accounts, sessions, users, verificationTokens } from "db/schema";
import { User } from "@/types/database-types";
import { eq } from "drizzle-orm";
import Google from "next-auth/providers/google";
import Resend from "next-auth/providers/resend";

declare module "next-auth" {
	/**
	 * Returned by `auth`, `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context
	 */
	interface Session {
		user: User & DefaultSession["user"];
	}
}

export const { handlers, signIn, signOut, auth } = NextAuth({
	adapter: DrizzleAdapter(getDatabaseClient(), {
		usersTable: users,
		accountsTable: accounts,
		sessionsTable: sessions,
		verificationTokensTable: verificationTokens,
	}),
	session: { strategy: "jwt" },
	callbacks: {
		session: async ({ session }) => {
			const db = getDatabaseClient();
			const user = await db.query.users.findFirst({
				where: eq(users.email, session.user.email),
			});

			session.user = { ...user, ...session.user };
			return session;
		},
	},
	providers: [Google, Resend],
});

@the-me-0
Copy link

Hello there !
I'm currently running in this issue while trying to get prisma to run in nextjs edge runtime. Their documentation is telling me to use something like this :

import { Pool } from 'pg';
import { PrismaPg } from '@prisma/adapter-pg';
import { PrismaClient } from '@prisma/client';

const pool = new Pool({ connectionString });
const adapter = new PrismaPg(pool);
const prisma = new PrismaClient({ adapter });

but as soon as I make a database call, I get this kind of error :

Module not found: Can't resolve 'fs'
https://nextjs.org/docs/messages/module-not-found

Import trace for requested module:
./node_modules/pg/lib/connection-parameters.js
./node_modules/pg/lib/client.js
./node_modules/pg/lib/index.js
./instrumentation.ts

As you can see, the error originates from the "pg" library. I'm gonna be completely honest and tell you that I don't really know what the "pg" is (although I guess it allows to connect to postgres databases without using TCP). I'm gonna try to create a minimal repo that recreates this behaviour asap, but reading this whole issue comments I did not see a solution come out yet.

Have a nice day, and do not hesitate to ping me if you manage to get results on this matter.

@the-me-0
Copy link

Minimal repro of my situation here : https://github.com/the-me-0/node-pg-minimal-repro
I'm still trying to resolve it on my side, and I'll keep you updated if I find anything.

@andyjy
Copy link

andyjy commented Nov 12, 2024

@the-me-0 pg isn't compatible with Next.js Edge Runtime (which == Vercel Edge Functions). Next.js doesn't support all Cloudflare's APIs - in particular the required connect().

In order to use Prisma with Next.js Edge, you need to use a supported Prisma Driver Adapter/database combination here:
https://www.prisma.io/docs/orm/prisma-client/deployment/edge/overview#which-database-drivers-are-edge-compatible .

Note that page says:

node-postgres (pg) uses Cloudflare's connect() (TCP) to access the database. It is only compatible with Cloudflare Workers, not with Vercel Edge Functions.

In other words, pg does work when used directly with Cloudflare Workers - but to do this you'd need to use a different framework, not Next.js. You could use something more lightweight like Hono - or even no framework at all, as in the Prisma guide for Cloudflare Workers

@the-me-0
Copy link

the-me-0 commented Nov 13, 2024

I did read this page yesterday, and I am aware that pg cannot run in nextjs's edge runtime. But this issue is still open, so isn't that a thing "pg" is aiming to fix ? If so, my repro could help. If not, this issue should be closed.

I needed pg to work in this edge runtime because no other solution really cut it for me (fortunately, I found a way around, documented on the prisma issue : prisma/prisma#24430 (comment)), as I have a local DB running on docker and that's what I'm trying to connect to. I'll admit that I did not try to use other drivers proposed by the prisma documentation, as I did not know if they would work for my "localhost" set-up. I don't even know what's a cloudflare worker is tbh so I went for the option that seemed to be the simplest, node-postgres.

Maybe other adapters like neon would have done the work and I just lost a lot of time for nothing, but in any case I got something to work now.

@mkpanq
Copy link

mkpanq commented Jan 14, 2025

For all who uses drizzle ORM with node-postgres adapter - I've also had Error: The edge runtime does not support Node.js 'crypto' module.
My solution was to replace driver from node-postgres to postgres.js - more info about it here

Hope it's gonna be possibile in your projects !

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

No branches or pull requests