PlanetScale is a managed MySQL host built around Vitess, branching, deploy requests, and a fetch-based HTTP driver. Because @planetscale/database uses plain fetch, it runs on every runtime DaloyJS supports, including Cloudflare Workers and Vercel. If you are using PlanetScale Postgres, follow the Neon driver pattern instead.
One HTTP driver, every runtime
DaloyJS routehandler reads state.db
app.decorate("db", db)db.execute(sql, params)
@planetscale/databasefetch-based HTTP driver
NodeBunDenoWorkersVercel
PlanetScalemanaged MySQL on Vitess
branchesdeploy requests
Because @planetscale/database speaks plain fetch instead of a raw TCP socket, the same data-access code runs on every runtime DaloyJS targets, including Cloudflare Workers and Vercel.
1. Provision and grab credentials
Create a database at app.planetscale.com, generate a password, and copy the host plus credentials. Set them as DATABASE_HOST, DATABASE_USERNAME, and DATABASE_PASSWORD.
2. Install
ts
pnpm add @planetscale/database
3. Create a PlanetScale plugin
ts
// src/db/planetscale.ts import { connect } from "@planetscale/database";import type { App } from "@daloyjs/core"; export const db = connect({ host: process.env.DATABASE_HOST!, username: process.env.DATABASE_USERNAME!, password: process.env.DATABASE_PASSWORD!,}); export type Db = typeof db;export const planetscalePlugin = { name: "planetscale", register(app: App) { app.decorate("db", db); },};
4. Augment app state
ts
// src/types/state.d.tsimport type { Db } from "../db/planetscale";declare module "@daloyjs/core" { interface AppState { db: Db; }}
Construct the connection inside the worker handler so it picks up the binding from env, then call app.fetch(req). If your app does not need worker bindings, you can export the standard Cloudflare adapterdirectly.
Use the PlanetScale Driver Adapter (GA since Prisma 6.16.0). PlanetScale disables foreign-key constraints by default on MySQL unless you enable them in database settings, so set relationMode = "prisma"in your schema.prisma when you are using the default no-FK mode, and point DATABASE_URL at the serverless host (aws.connect.psdb.cloud).
ts
pnpm add @prisma/adapter-planetscale// src/db/prisma.tsimport { PrismaClient } from "@prisma/client";import { PrismaPlanetScale } from "@prisma/adapter-planetscale";const adapter = new PrismaPlanetScale({ url: process.env.DATABASE_URL! });export const prisma = new PrismaClient({ adapter });
On Node.js versions older than 18 (no global fetch), install undici and pass { fetch: undiciFetch } as a second option.
Branching & deploy requests
PlanetScale's schema workflow uses branches and deploy requests rather than ad-hoc ALTER TABLE. Pair this with your CI: run migrations against a development branch, open a deploy request, and merge to main. The same Daloy app code works against any branch, just swap the host.