Implements PlanetScale serverless MySQL with branching workflows, non-blocking schema changes, and Prisma integration. Use when building apps with PlanetScale, implementing database branching, or needing serverless MySQL.
Adds PlanetScale serverless MySQL database capabilities with Prisma integration. Use when building apps with PlanetScale, implementing database branching workflows, or needing non-blocking schema changes.
/plugin marketplace add mgd34msu/goodvibes-plugin/plugin install goodvibes@goodvibes-marketThis skill inherits all available tools. When active, it can use any tool Claude has access to.
references/branching.mdreferences/migration.mdPlanetScale is a serverless MySQL-compatible database built on Vitess, offering database branching, non-blocking schema changes, and horizontal scaling.
# Install CLI
brew install planetscale/tap/pscale
# Authenticate
pscale auth login
# Create database
pscale database create my-app --region us-east
# Create branch
pscale branch create my-app feature-users
# Connect to branch
pscale connect my-app feature-users --port 3309
mysql://username:password@aws.connect.psdb.cloud/database?ssl={"rejectUnauthorized":true}
npm install prisma @prisma/client
npm install @prisma/adapter-planetscale # For serverless
// prisma/schema.prisma
generator client {
provider = "prisma-client-js"
previewFeatures = ["driverAdapters"] // For serverless driver
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
relationMode = "prisma" // Required if FK constraints disabled
}
model User {
id String @id @default(cuid())
email String @unique
name String?
posts Post[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([email])
}
model Post {
id String @id @default(cuid())
title String
content String? @db.Text
published Boolean @default(false)
authorId String
author User @relation(fields: [authorId], references: [id])
createdAt DateTime @default(now())
@@index([authorId]) // Required when using relationMode = "prisma"
}
# Push schema to branch (not migrate)
npx prisma db push
# Generate client
npx prisma generate
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
// CRUD operations work normally
const user = await prisma.user.create({
data: {
email: 'user@example.com',
name: 'John Doe'
}
})
const users = await prisma.user.findMany({
include: { posts: true }
})
import { PrismaClient } from '@prisma/client'
import { PrismaPlanetScale } from '@prisma/adapter-planetscale'
import { Client } from '@planetscale/database'
// Create PlanetScale client
const client = new Client({
url: process.env.DATABASE_URL
})
// Create Prisma adapter
const adapter = new PrismaPlanetScale(client)
// Create Prisma client with adapter
const prisma = new PrismaClient({ adapter })
export default prisma
# Create feature branch from main
pscale branch create my-app add-comments
# Connect and develop
pscale connect my-app add-comments --port 3309
# Make schema changes on branch
npx prisma db push
# Create deploy request (like a PR)
pscale deploy-request create my-app add-comments
# Review diff
pscale deploy-request diff my-app 1
# Deploy to main
pscale deploy-request deploy my-app 1
PlanetScale performs schema changes without locking tables:
-- These are safe to run in production
ALTER TABLE users ADD COLUMN avatar_url VARCHAR(255);
ALTER TABLE posts ADD INDEX idx_created_at (created_at);
import { connect } from '@planetscale/database'
const conn = connect({
host: process.env.DATABASE_HOST,
username: process.env.DATABASE_USERNAME,
password: process.env.DATABASE_PASSWORD
})
// Execute query
const results = await conn.execute('SELECT * FROM users WHERE id = ?', [userId])
// Transaction-like batch (not true ACID)
const results = await conn.transaction(async (tx) => {
await tx.execute('INSERT INTO users (email) VALUES (?)', ['user@example.com'])
await tx.execute('INSERT INTO profiles (user_id) VALUES (?)', [1])
return tx.execute('SELECT * FROM users WHERE id = ?', [1])
})
Enable in PlanetScale Dashboard > Settings > Beta features:
// Then use normal Prisma schema
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
// No relationMode needed
}
model Post {
id String @id
authorId String
author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
}
When FK constraints are disabled:
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
relationMode = "prisma" // Emulates FKs in Prisma
}
model Post {
id String @id
authorId String
author User @relation(fields: [authorId], references: [id])
@@index([authorId]) // Must add indexes manually
}
# .env
DATABASE_URL="mysql://username:password@aws.connect.psdb.cloud/mydb?sslaccept=strict"
# For serverless driver
DATABASE_HOST="aws.connect.psdb.cloud"
DATABASE_USERNAME="your-username"
DATABASE_PASSWORD="your-password"
// app/api/users/route.ts
import prisma from '@/lib/prisma'
import { NextResponse } from 'next/server'
export async function GET() {
const users = await prisma.user.findMany()
return NextResponse.json(users)
}
export async function POST(request: Request) {
const body = await request.json()
const user = await prisma.user.create({
data: {
email: body.email,
name: body.name
}
})
return NextResponse.json(user)
}
// app/users/page.tsx
import prisma from '@/lib/prisma'
export default async function UsersPage() {
const users = await prisma.user.findMany({
orderBy: { createdAt: 'desc' }
})
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
)
}
PlanetScale handles connection pooling automatically. For high-traffic apps:
// Singleton pattern for Prisma
import { PrismaClient } from '@prisma/client'
const globalForPrisma = globalThis as unknown as {
prisma: PrismaClient | undefined
}
export const prisma = globalForPrisma.prisma ?? new PrismaClient({
log: process.env.NODE_ENV === 'development' ? ['query'] : []
})
if (process.env.NODE_ENV !== 'production') {
globalForPrisma.prisma = prisma
}
export default prisma
# Database operations
pscale database create <db> --region <region>
pscale database delete <db>
pscale database list
# Branch operations
pscale branch create <db> <branch>
pscale branch delete <db> <branch>
pscale branch list <db>
pscale branch schema <db> <branch>
# Connect for local dev
pscale connect <db> <branch> --port 3309
# Deploy requests
pscale deploy-request create <db> <branch>
pscale deploy-request list <db>
pscale deploy-request diff <db> <number>
pscale deploy-request deploy <db> <number>
pscale deploy-request close <db> <number>
# Password management
pscale password create <db> <branch> <name>
pscale password list <db> <branch>
View in Dashboard > Insights:
// Log connection stats
const prisma = new PrismaClient({
log: [
{ level: 'query', emit: 'event' },
{ level: 'error', emit: 'stdout' }
]
})
prisma.$on('query', (e) => {
console.log(`Query: ${e.query}`)
console.log(`Duration: ${e.duration}ms`)
})
relationMode = "prisma"db push not migrate - PlanetScale manages its own migrationsThis skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.