Skip to content

feat(examples): add Prisma + Hyperdrive example#609

Open
JamesbbBriz wants to merge 1 commit intocloudflare:mainfrom
JamesbbBriz:examples/prisma-hyperdrive
Open

feat(examples): add Prisma + Hyperdrive example#609
JamesbbBriz wants to merge 1 commit intocloudflare:mainfrom
JamesbbBriz:examples/prisma-hyperdrive

Conversation

@JamesbbBriz
Copy link

Summary

Add a full-stack CRUD example demonstrating Prisma v7 with Hyperdrive on Cloudflare Workers. This is the first database example in the repo — fills a major gap for users migrating data-driven apps to vinext.

What it shows

Structure

examples/prisma-hyperdrive/
├── app/
│   ├── layout.tsx              # Root layout
│   ├── page.tsx                # Server component: list items from DB
│   └── api/items/route.ts      # GET + POST route handler
├── lib/db.ts                   # Per-request Prisma client (50ms TTL pattern)
├── prisma/schema.prisma        # Simple Item model
├── vite.config.ts              # Standard vinext + cloudflare config
├── wrangler.jsonc              # Hyperdrive binding
└── worker/index.ts             # Uses virtual:vinext-app-handler

Key pattern: per-request client

let cached: PrismaClient | null = null;
let cachedAt = 0;

export function getPrisma(): PrismaClient {
  const now = Date.now();
  if (cached && now - cachedAt < 50) return cached;
  const pool = new Pool({ connectionString: env.HYPERDRIVE.connectionString });
  cached = new PrismaClient({ adapter: new PrismaPg(pool) });
  cachedAt = now;
  return cached;
}

This pattern is production-validated — we run it on Workers Free plan (10ms CPU limit) with zero alternating failures.

Blast radius

Zero — new directory only, no changes to existing code.

Relates to #537

Full-stack CRUD example demonstrating:
- Per-request PrismaClient (solves alternating connection failures on Workers)
- Hyperdrive connection pooling via cloudflare:workers binding
- Server component data fetching with Prisma
- Route handler CRUD API using standard Web Request/Response
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0731fd6e29

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

*/

// @ts-expect-error -- virtual module resolved by vinext at build time
export { default } from "virtual:vinext-app-handler";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Import the supported vinext app entry

virtual:vinext-app-handler is not a virtual module that vinext resolves, so this export will fail during bundling with an unresolved import and the example cannot build/deploy. In packages/vinext/src/index.ts, the resolver only handles IDs like virtual:vinext-rsc-entry, virtual:vinext-app-ssr-entry, and virtual:vinext-app-browser-entry (or the non-virtual vinext/server/app-router-entry).

Useful? React with 👍 / 👎.

Comment on lines +35 to +36
if (cached && now - cachedAt < 50) {
return cached;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Stop reusing Prisma client across requests

This time-based cache is not actually request-scoped: two different requests that arrive within 50ms (including concurrent requests in one Worker isolate) will receive the same PrismaClient. Since this example’s rationale is avoiding cross-request connection reuse, this condition can reintroduce the same class of failures under load and makes behavior nondeterministic by request timing.

Useful? React with 👍 / 👎.

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

Successfully merging this pull request may close these issues.

1 participant