P
Prisma•3w ago
verdverm.com

Next + Cloudflare Workers + D1

I'm trying to use Prisma in a Next app on Cloudflare Workers and D1. I have gone through all the setup steps and tried to use the ...FORCE_WASM...=1 But on actual deploy, I keep getting fs.readdir not available. My understanding is that this should work, that prisma supports edge runtimes (examples for prisma+d1 exist), and that something is not being built or setup right such that prisma doesn't try to use functions it knows it shouldn't in an edge runtime
26 Replies
Prisma AI Help
Prisma AI Help•3w ago
You selected to wait for the human sages. They'll share their wisdom soon. Grab some tea while you wait, or check out #ask-ai if you'd like a quick chat with the bot anyway!
Nurul
Nurul•3w ago
Hey 👋 Is your repository open source? Any way I can try to run the example and debug?
verdverm.com
verdverm.comOP•3w ago
yes, I have a minimal repro for another cloudflare edge runtime issue I'm hitting. Let me make sure I can reproduce the prisma specific issue and point you at the specifics after
verdverm.com
verdverm.comOP•3w ago
@Nurul (Prisma) See this directory: https://github.com/verdverm/cf-repro/tree/main/src/app/repro works when yarn dev fails with the above error with yarn worker:dev
GitHub
cf-repro/src/app/repro at main · verdverm/cf-repro
repro repo for my cf frens. Contribute to verdverm/cf-repro development by creating an account on GitHub.
Joshkop
Joshkop•2w ago
Im having the same problem Not with D1 but tried the pg-adapter and even signed up for neon and used that adapter Stacktrace:
✘ [ERROR] ⨯ Error: [unenv] fs.readdir is not implemented yet!

at createNotImplementedError
(file:///home/joshkop/projects/test/node_modules/.pnpm/[email protected]/node_modules/unenv/runtime/_internal/utils.mjs:22:10)
at Object.fn [as readdir]
(file:///home/joshkop/projects/test/node_modules/.pnpm/[email protected]/node_modules/unenv/runtime/_internal/utils.mjs:26:11)
at Wu
(file:///home/joshkop/projects/test/.open-next/server-functions/default/handler.mjs:370385:34)
at qo
(file:///home/joshkop/projects/test/.open-next/server-functions/default/handler.mjs:370378:23)
at Ju
(file:///home/joshkop/projects/test/.open-next/server-functions/default/handler.mjs:370361:27)
at async Bo
(file:///home/joshkop/projects/test/.open-next/server-functions/default/handler.mjs:370307:128)
at async Qo
(file:///home/joshkop/projects/test/.open-next/server-functions/default/handler.mjs:370407:15)
at async nt
(file:///home/joshkop/projects/test/.open-next/server-functions/default/handler.mjs:370393:33)
at async Object.getCurrentBinaryTarget
(file:///home/joshkop/projects/test/.open-next/server-functions/default/handler.mjs:374595:19)
at async Object.instantiateLibrary
(file:///home/joshkop/projects/test/.open-next/server-functions/default/handler.mjs:374589:35)
{
clientVersion: '6.3.1'
}
✘ [ERROR] ⨯ Error: [unenv] fs.readdir is not implemented yet!

at createNotImplementedError
(file:///home/joshkop/projects/test/node_modules/.pnpm/[email protected]/node_modules/unenv/runtime/_internal/utils.mjs:22:10)
at Object.fn [as readdir]
(file:///home/joshkop/projects/test/node_modules/.pnpm/[email protected]/node_modules/unenv/runtime/_internal/utils.mjs:26:11)
at Wu
(file:///home/joshkop/projects/test/.open-next/server-functions/default/handler.mjs:370385:34)
at qo
(file:///home/joshkop/projects/test/.open-next/server-functions/default/handler.mjs:370378:23)
at Ju
(file:///home/joshkop/projects/test/.open-next/server-functions/default/handler.mjs:370361:27)
at async Bo
(file:///home/joshkop/projects/test/.open-next/server-functions/default/handler.mjs:370307:128)
at async Qo
(file:///home/joshkop/projects/test/.open-next/server-functions/default/handler.mjs:370407:15)
at async nt
(file:///home/joshkop/projects/test/.open-next/server-functions/default/handler.mjs:370393:33)
at async Object.getCurrentBinaryTarget
(file:///home/joshkop/projects/test/.open-next/server-functions/default/handler.mjs:374595:19)
at async Object.instantiateLibrary
(file:///home/joshkop/projects/test/.open-next/server-functions/default/handler.mjs:374589:35)
{
clientVersion: '6.3.1'
}
fs.readdir seems to be called here:
async function Wu(e) {
try {
return (await ti.default.readdir(e)).find((r) => r.startsWith("libssl.so.") && !r.startsWith("libssl.so.0"));
} catch (t) {
if (t.code === "ENOENT")
return;
throw t;
}
}
async function Wu(e) {
try {
return (await ti.default.readdir(e)).find((r) => r.startsWith("libssl.so.") && !r.startsWith("libssl.so.0"));
} catch (t) {
if (t.code === "ENOENT")
return;
throw t;
}
}
@Nurul (Prisma)
verdverm.com
verdverm.comOP•2w ago
PRISMA_CLIENT_FORCE_WASM=1 is supposed to fix this, but it does not
yarn prisma -v
yarn run v1.22.21
$ /Users/tony/verdverm/cf-repro/node_modules/.bin/prisma -v
Environment variables loaded from .env
prisma : 6.3.0
@prisma/client : 6.3.0
Computed binaryTarget : darwin-arm64
Operating System : darwin
Architecture : arm64
Node.js : v21.7.1
TypeScript : 5.7.3
Query Engine (Node-API) : libquery-engine acc0b9dd43eb689cbd20c9470515d719db10d0b0 (at node_modules/@prisma/engines/libquery_engine-darwin-arm64.dylib.node)
Schema Engine : schema-engine-cli acc0b9dd43eb689cbd20c9470515d719db10d0b0 (at node_modules/@prisma/engines/schema-engine-darwin-arm64)
Schema Wasm : @prisma/prisma-schema-wasm 6.3.0-17.acc0b9dd43eb689cbd20c9470515d719db10d0b0
Default Engines Hash : acc0b9dd43eb689cbd20c9470515d719db10d0b0
Studio : 0.508.0
Preview Features : driverAdapters
yarn prisma -v
yarn run v1.22.21
$ /Users/tony/verdverm/cf-repro/node_modules/.bin/prisma -v
Environment variables loaded from .env
prisma : 6.3.0
@prisma/client : 6.3.0
Computed binaryTarget : darwin-arm64
Operating System : darwin
Architecture : arm64
Node.js : v21.7.1
TypeScript : 5.7.3
Query Engine (Node-API) : libquery-engine acc0b9dd43eb689cbd20c9470515d719db10d0b0 (at node_modules/@prisma/engines/libquery_engine-darwin-arm64.dylib.node)
Schema Engine : schema-engine-cli acc0b9dd43eb689cbd20c9470515d719db10d0b0 (at node_modules/@prisma/engines/schema-engine-darwin-arm64)
Schema Wasm : @prisma/prisma-schema-wasm 6.3.0-17.acc0b9dd43eb689cbd20c9470515d719db10d0b0
Default Engines Hash : acc0b9dd43eb689cbd20c9470515d719db10d0b0
Studio : 0.508.0
Preview Features : driverAdapters
@Joshkop walking back from our errors, to the code you found, we may need to set the binaryTargets field in our prisma files. It looks like they are poking around the filesystem to figure out what platform they are running on, what version of libssl to use... but we may be able to short-cirtuit these checks
at async nt (Users/tony/verdverm/cf-repro/.wrangler/tmp/dev-6wv4fh/worker.js:260633:33)
at async Object.getCurrentBinaryTarget
(Users/tony/verdverm/cf-repro/.wrangler/tmp/dev-6wv4fh/worker.js:265144:19)
at async Object.instantiateLibrary
(Users/tony/verdverm/cf-repro/.wrangler/tmp/dev-6wv4fh/worker.js:265138:35) {
clientVersion: '6.3.0'
}
at async nt (Users/tony/verdverm/cf-repro/.wrangler/tmp/dev-6wv4fh/worker.js:260633:33)
at async Object.getCurrentBinaryTarget
(Users/tony/verdverm/cf-repro/.wrangler/tmp/dev-6wv4fh/worker.js:265144:19)
at async Object.instantiateLibrary
(Users/tony/verdverm/cf-repro/.wrangler/tmp/dev-6wv4fh/worker.js:265138:35) {
clientVersion: '6.3.0'
}
https://github.com/prisma/prisma/blob/02090bb22a32c96dc69f9efb21f70c61191b6478/packages/client/src/runtime/core/engines/library/LibraryEngine.ts#L245
private async getCurrentBinaryTarget() {
if (TARGET_BUILD_TYPE === 'library') {
if (this.binaryTarget) return this.binaryTarget
const binaryTarget = await this.tracingHelper.runInChildSpan('detect_platform', () =>
getBinaryTargetForCurrentPlatform(),
)
private async getCurrentBinaryTarget() {
if (TARGET_BUILD_TYPE === 'library') {
if (this.binaryTarget) return this.binaryTarget
const binaryTarget = await this.tracingHelper.runInChildSpan('detect_platform', () =>
getBinaryTargetForCurrentPlatform(),
)
https://www.prisma.io/docs/orm/prisma-client/deployment/serverless/deploy-to-netlify#binary-targets-in-schemaprisma did not seem to help
verdverm.com
verdverm.comOP•2w ago
found this very detaild compat chart for CF workers (wrangler) https://workers-nodejs-compat-matrix.pages.dev/
Joshkop
Joshkop•2w ago
Didn't work for me as well it still tries to get the binary target through the failing function I don't think the node compat should apply here since Prisma should be edge compatible with the adapters Since they also have docs for clouflare workers on prisma
verdverm.com
verdverm.comOP•2w ago
💯 seems like there is a disconnect somwhere between prisma, wrangler, open-next, and cloudflare I may just write SQL by hand and use D1 directly, just use prisma for sql creation, maybe even drop Prisma completely
Joshkop
Joshkop•2w ago
Are you running the wrangler preview in wsl2? You might try out drizzle
verdverm.com
verdverm.comOP•2w ago
I'm on the latest wrangler on mac
Joshkop
Joshkop•2w ago
Drizzle ORM - Cloudflare D1
Drizzle ORM is a lightweight and performant TypeScript ORM with developer experience in mind.
Joshkop
Joshkop•2w ago
Ok then I don't see anything which our repos have in commen other then Prisma opennext and wrangler
verdverm.com
verdverm.comOP•2w ago
I don't mind writing the sql by hand honestly, just thought I'd use prisma because it generates migration files for me and lets me see the full model without having to piece it together over multiple migration files or inspecting the database It's really not that bad
import { NextRequest, NextResponse } from 'next/server';
import { getCloudflareContext } from "@opennextjs/cloudflare";

const stmt = `
SELECT
user.did, user.handle, password_session.key
FROM user
INNER JOIN password_session
ON user.id = password_session.user_id
`;

type User = {
did: string
handle: string
key: string
}

export async function GET(req: NextRequest) {
// Get handles to storage
const env = getCloudflareContext().env
const result = await env.DB.prepare(stmt).run<User>();

return NextResponse.json(result)
}
import { NextRequest, NextResponse } from 'next/server';
import { getCloudflareContext } from "@opennextjs/cloudflare";

const stmt = `
SELECT
user.did, user.handle, password_session.key
FROM user
INNER JOIN password_session
ON user.id = password_session.user_id
`;

type User = {
did: string
handle: string
key: string
}

export async function GET(req: NextRequest) {
// Get handles to storage
const env = getCloudflareContext().env
const result = await env.DB.prepare(stmt).run<User>();

return NextResponse.json(result)
}
Joshkop
Joshkop•2w ago
Yeah I really want the typescript support for the models But drizzle also has that and migrations
verdverm.com
verdverm.comOP•2w ago
not using an ORM means it is much easier to move to another language like Go
Joshkop
Joshkop•2w ago
But I'm pretty far along and switching would take a lot of time
verdverm.com
verdverm.comOP•2w ago
or share the SQL between microservices
verdverm.com
verdverm.comOP•2w ago
Drizzle ORM - Migrations
Drizzle ORM is a lightweight and performant TypeScript ORM with developer experience in mind.
verdverm.com
verdverm.comOP•2w ago
the silence from Prisma here gives me pause too
Joshkop
Joshkop•2w ago
I still think there has to be some build config or whatever which is our problem Or it's something which opennext introduced in a recent version Can't think we're the only people trying nextjs Prisma and CF workers And the only info anywhere with this problem is this discord thread
verdverm.com
verdverm.comOP•2w ago
agree on all of that!
Joshkop
Joshkop•2w ago
What part ? I think option 4 is just like prisms migrations
verdverm.com
verdverm.comOP•2w ago
mostly the UX of it, don't give me blocks of little text to figure out what option I need, use headings, and don't make me click to expand details
Joshkop
Joshkop•2w ago
Ahh yeah fair enough Anyways Ill see if i can migrate over to drizzle without too much hassle and try that out Dont think we'll get a solution here in the near future
verdverm.com
verdverm.comOP•2w ago
I'm now hoping that Prisma is also causing my OAuth problems because the client get/set helpers are using Prisma to r/w

Did you find this page helpful?