install
source · Clone the upstream repo
git clone https://github.com/ComeOnOliver/skillshub
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/ComeOnOliver/skillshub "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/TerminalSkills/skills/planetscale" ~/.claude/skills/comeonoliver-skillshub-planetscale && rm -rf "$T"
manifest:
skills/TerminalSkills/skills/planetscale/SKILL.mdsource content
PlanetScale — Serverless MySQL Platform
Overview
PlanetScale, the serverless MySQL platform built on Vitess (the database clustering system powering YouTube). Helps developers set up databases with Git-like branching for schema changes, non-blocking schema migrations, and connection pooling for serverless environments.
Instructions
CLI Operations
# Install PlanetScale CLI brew install planetscale/tap/pscale # Authenticate pscale auth login # Create a database pscale database create my-app --region us-east # Connect to your database (opens a local proxy) pscale connect my-app main --port 3306 # Now connect your app to localhost:3306 with no password # Create a branch (like git branch, for schema changes) pscale branch create my-app add-orders-table # Connect to the branch for testing pscale connect my-app add-orders-table --port 3307 # Open a shell on the branch pscale shell my-app add-orders-table
Schema Branching
-- On the "add-orders-table" branch, make schema changes safely -- These changes don't affect the main branch until you merge CREATE TABLE orders ( id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, user_id BIGINT NOT NULL, amount DECIMAL(10, 2) NOT NULL, currency VARCHAR(3) NOT NULL DEFAULT 'USD', status ENUM('pending', 'processing', 'completed', 'refunded') NOT NULL DEFAULT 'pending', metadata JSON, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_user_id (user_id), INDEX idx_status_created (status, created_at) ); -- Add columns to existing tables ALTER TABLE users ADD COLUMN stripe_customer_id VARCHAR(255); ALTER TABLE users ADD INDEX idx_stripe_customer (stripe_customer_id);
# Create a deploy request (like a pull request for schema changes) pscale deploy-request create my-app add-orders-table # Review the deploy request pscale deploy-request diff my-app 1 # Deploy (non-blocking — zero downtime) pscale deploy-request deploy my-app 1 # Schema changes are applied without locking tables # PlanetScale uses Vitess's online DDL (gh-ost) under the hood
Application Integration
// src/lib/db.ts — Connect to PlanetScale import { connect } from "@planetscale/database"; // Serverless driver (HTTP-based, works in edge functions) const db = connect({ host: process.env.DATABASE_HOST, username: process.env.DATABASE_USERNAME, password: process.env.DATABASE_PASSWORD, }); // Query async function getOrders(userId: string) { const results = await db.execute( "SELECT * FROM orders WHERE user_id = ? ORDER BY created_at DESC LIMIT 20", [userId] ); return results.rows; } // Insert async function createOrder(order: { userId: string; amount: number; currency: string }) { const result = await db.execute( "INSERT INTO orders (user_id, amount, currency) VALUES (?, ?, ?)", [order.userId, order.amount, order.currency] ); return result.insertId; } // Transaction async function processRefund(orderId: string) { await db.transaction(async (tx) => { await tx.execute( "UPDATE orders SET status = 'refunded' WHERE id = ? AND status = 'completed'", [orderId] ); const order = await tx.execute("SELECT * FROM orders WHERE id = ?", [orderId]); await tx.execute( "INSERT INTO refunds (order_id, amount) VALUES (?, ?)", [orderId, order.rows[0].amount] ); }); }
With Prisma ORM
// prisma/schema.prisma — PlanetScale with Prisma generator client { provider = "prisma-client-js" } datasource db { provider = "mysql" url = env("DATABASE_URL") relationMode = "prisma" // Required: PlanetScale doesn't support foreign keys } model User { id Int @id @default(autoincrement()) email String @unique name String plan String @default("free") orders Order[] createdAt DateTime @default(now()) @map("created_at") @@map("users") } model Order { id Int @id @default(autoincrement()) userId Int @map("user_id") amount Decimal @db.Decimal(10, 2) status String @default("pending") user User @relation(fields: [userId], references: [id]) createdAt DateTime @default(now()) @map("created_at") @@index([userId]) @@index([status, createdAt]) @@map("orders") }
# Push schema changes via Prisma (on a branch) pscale connect my-app add-orders-table --port 3309 & DATABASE_URL="mysql://root@localhost:3309/my-app" npx prisma db push
Insights and Monitoring
# View query insights (slow queries, most frequent queries) pscale query-insights my-app main # View database size and row counts pscale database show my-app # Audit log pscale audit-log list my-app
Installation
# CLI brew install planetscale/tap/pscale # Serverless driver (Node.js) npm install @planetscale/database # With Prisma npm install prisma @prisma/client
Examples
Example 1: Setting up Planetscale with a custom configuration
User request:
I just installed Planetscale. Help me configure it for my TypeScript + React workflow with my preferred keybindings.
The agent creates the configuration file with TypeScript-aware settings, configures relevant plugins/extensions for React development, sets up keyboard shortcuts matching the user's preferences, and verifies the setup works correctly.
Example 2: Extending Planetscale with custom functionality
User request:
I want to add a custom schema branching to Planetscale. How do I build one?
The agent scaffolds the extension/plugin project, implements the core functionality following Planetscale's API patterns, adds configuration options, and provides testing instructions to verify it works end-to-end.
Guidelines
- Branch for every schema change — Never modify main directly; create a branch, test, then deploy via deploy request
- No foreign key constraints — PlanetScale (Vitess) doesn't support FK constraints; use
or enforce in application coderelationMode = "prisma" - Serverless driver for edge — Use
(HTTP-based) for Vercel Edge, Cloudflare Workers; use mysql2 for Node.js servers@planetscale/database - Non-blocking migrations — PlanetScale applies ALTER TABLE without locking; deploy schema changes during business hours safely
- Deploy request review — Treat deploy requests like pull requests; review the diff before deploying to production
- Index before you need them — Add indexes on columns you filter/sort by; PlanetScale's query insights shows which queries need them
- Connection string from environment — Use
for local dev (no password needed); use connection strings in productionpscale connect - Read replicas for read-heavy apps — PlanetScale supports read-only regions; route read queries to replicas for lower latency