tessl install https://github.com/secondsky/claude-skills --skill neon-vercel-postgresgithub.com/secondsky/claude-skills
Neon + Vercel serverless Postgres for edge and serverless environments. Use for Cloudflare Workers, Vercel Edge, Next.js apps with HTTP/WebSocket connections, database branching (git-like), Drizzle/Prisma ORM integration, migrations, PITR backups, or encountering connection pool exhausted errors, TCP connection issues, SSL config problems.
Review Score
85%
Validation Score
13/16
Implementation Score
73%
Activation Score
100%
Status: Production Ready
Last Updated: 2025-11-21
Dependencies: None
Latest Versions: @neondatabase/serverless@1.0.2, @vercel/postgres@0.10.0, drizzle-orm@0.44.7, neonctl@2.16.1
Option A: Neon Direct (multi-cloud, Cloudflare Workers, any serverless)
bun add @neondatabase/serverlessOption B: Vercel Postgres (Vercel-only, zero-config on Vercel)
bun add @vercel/postgresWhy this matters:
For Neon Direct:
# Sign up at https://neon.tech
# Create a project → Get connection string
# Format: postgresql://user:password@ep-xyz-pooler.region.aws.neon.tech/dbname?sslmode=requireFor Vercel Postgres:
# In your Vercel project
vercel postgres create
vercel env pull .env.local # Automatically creates POSTGRES_URL and other varsCRITICAL:
-pooler.region.aws.neon.tech)?sslmode=require parameterNeon Direct:
import { neon } from '@neondatabase/serverless';
const sql = neon(process.env.DATABASE_URL!);
// Simple query
const users = await sql`SELECT * FROM users WHERE id = ${userId}`;
// Transactions
const result = await sql.transaction([
sql`INSERT INTO users (name) VALUES (${name})`,
sql`SELECT * FROM users WHERE name = ${name}`
]);Vercel Postgres:
import { sql } from '@vercel/postgres';
// Simple query
const { rows } = await sql`SELECT * FROM users WHERE id = ${userId}`;
// Transactions
const client = await sql.connect();
try {
await client.sql`BEGIN`;
await client.sql`INSERT INTO users (name) VALUES (${name})`;
await client.sql`COMMIT`;
} finally {
client.release();
}CRITICAL:
sql`...`) for automatic SQL injection protectionsql('SELECT * FROM users WHERE id = ' + id) ❌✅ Use pooled connection strings for serverless environments (-pooler. in hostname)
✅ Use template tag syntax for queries (sql`SELECT * FROM users`) to prevent SQL injection
✅ Include sslmode=require in connection strings
✅ Release connections after transactions (Vercel Postgres manual transactions)
✅ Use Drizzle ORM for edge-compatible TypeScript ORM (not Prisma in Cloudflare Workers)
✅ Set connection string as environment variable (never hardcode)
✅ Use Neon branching for preview environments and testing
✅ Monitor connection pool usage in Neon dashboard
✅ Handle errors with try/catch blocks and rollback transactions on failure
✅ Use RETURNING clause for INSERT/UPDATE to get created/updated data in one query
❌ Never use non-pooled connections in serverless functions (will exhaust connection pool)
❌ Never concatenate SQL strings ('SELECT * FROM users WHERE id = ' + id) - SQL injection risk
❌ Never omit sslmode=require - connections will fail or be insecure
❌ Never forget to client.release() in manual Vercel Postgres transactions - connection leak
❌ Never use Prisma in Cloudflare Workers - requires Node.js runtime (use Drizzle instead)
❌ Never hardcode connection strings - use environment variables
❌ Never run migrations from edge functions - use Node.js environment or Neon console
❌ Never commit .env files - add to .gitignore
❌ Never use POSTGRES_URL_NON_POOLING in serverless functions - defeats pooling
❌ Never exceed connection limits - monitor usage and upgrade plan if needed
Error: Error: connection pool exhausted or too many connections for role
Solution: Use pooled connection string (ends with -pooler.region.aws.neon.tech), not non-pooled
Error: Error: TCP connections are not supported in this environment
Solution: Use @neondatabase/serverless (HTTP-based), not pg or postgres.js (TCP-based)
Error: Successful SQL injection attack
Solution: Always use template tags (sql`SELECT * FROM users WHERE id = ${id}`), never concatenate strings
Error: Error: connection requires SSL
Solution: Always append ?sslmode=require to connection string
Error: Gradually increasing memory usage
Solution: Always call client.release() in finally block after manual transactions
Load references/error-catalog.md for all 15 errors with detailed solutions and troubleshooting guide.
When: Deploying serverless API with Postgres on Cloudflare Workers Quick Pattern:
import { neon } from '@neondatabase/serverless';
export default {
async fetch(request: Request, env: Env) {
const sql = neon(env.DATABASE_URL);
const users = await sql`SELECT * FROM users`;
return Response.json(users);
}
};Load: references/common-patterns.md → Pattern 1
When: Building Next.js app with Vercel Postgres Quick Pattern:
'use server';
import { sql } from '@vercel/postgres';
export async function getUsers() {
const { rows } = await sql`SELECT * FROM users`;
return rows;
}Load: references/common-patterns.md → Pattern 2
When: Need full TypeScript type safety and edge compatibility
Load: references/common-patterns.md → Pattern 3
When: Multiple operations must all succeed or all fail (e.g., money transfers)
Load: references/common-patterns.md → Pattern 4
When: Need isolated database for each pull request/preview deployment
Load: references/common-patterns.md → Pattern 5
Load references/setup-guide.md when:
Load references/error-catalog.md when:
Load references/common-patterns.md when:
Load references/advanced-topics.md when:
{
"dependencies": {
"@neondatabase/serverless": "^1.0.2"
}
}{
"dependencies": {
"@vercel/postgres": "^0.10.0"
}
}{
"dependencies": {
"@neondatabase/serverless": "^1.0.2",
"drizzle-orm": "^0.44.7"
},
"devDependencies": {
"drizzle-kit": "^0.31.0"
},
"scripts": {
"db:generate": "drizzle-kit generate",
"db:migrate": "drizzle-kit migrate",
"db:studio": "drizzle-kit studio"
}
}import { defineConfig } from 'drizzle-kit';
export default defineConfig({
schema: './db/schema.ts',
out: './db/migrations',
dialect: 'postgresql',
dbCredentials: {
url: process.env.DATABASE_URL!
}
});Why these settings:
@neondatabase/serverless is edge-compatible (HTTP/WebSocket-based)@vercel/postgres provides zero-config on Verceldrizzle-orm works in all runtimes (Cloudflare Workers, Vercel Edge, Node.js)drizzle-kit handles migrations and schema generationdrizzle-schema.ts - Complete Drizzle schema with users, posts, relations
// See templates/drizzle-schema.ts for full exampledrizzle-queries.ts - Common query patterns (SELECT, INSERT, UPDATE, DELETE, joins)
// See templates/drizzle-queries.ts for full exampledrizzle-migrations-workflow.md - Complete migration workflow guide
// See templates/drizzle-migrations-workflow.md for full guideneon-basic-queries.ts - Raw SQL query patterns with Neon
// See templates/neon-basic-queries.ts for full examplepackage.json - Complete dependency configuration
// See templates/package.json for full configRequired:
@neondatabase/serverless@^1.0.2 - Neon serverless Postgres client (HTTP/WebSocket-based)@vercel/postgres@^0.10.0 - Vercel Postgres client (alternative to Neon direct, Vercel-specific)Optional:
drizzle-orm@^0.44.7 - TypeScript ORM (edge-compatible, recommended)drizzle-kit@^0.31.0 - Drizzle schema migrations and introspection@prisma/client@^6.10.0 - Prisma ORM (Node.js only, not edge-compatible)@prisma/adapter-neon@^6.10.0 - Prisma adapter for Neon serverlessneonctl@^2.16.1 - Neon CLI for database managementzod@^3.24.0 - Schema validation for input sanitization/github/neondatabase/serverless, /github/vercel/storage{
"dependencies": {
"@neondatabase/serverless": "^1.0.2",
"@vercel/postgres": "^0.10.0",
"drizzle-orm": "^0.44.7"
},
"devDependencies": {
"drizzle-kit": "^0.31.0",
"neonctl": "^2.16.1"
}
}Latest Prisma (if needed):
{
"dependencies": {
"@prisma/client": "^6.10.0",
"@prisma/adapter-neon": "^6.10.0"
},
"devDependencies": {
"prisma": "^6.10.0"
}
}This skill is based on production deployments of Neon and Vercel Postgres:
Use this checklist to verify your setup:
@neondatabase/serverless or @vercel/postgres)-pooler.)?sslmode=requireDATABASE_URL or POSTGRES_URL)sql`...`)Questions? Issues?
references/error-catalog.md for all 15 errors and troubleshootingreferences/setup-guide.md for complete 7-step setup processreferences/common-patterns.md for production-tested code examplessslmode=require is in connection string