Use when setting up a production database for Bknd. Covers SQLite file, LibSQL/Turso, Cloudflare D1, PostgreSQL, Neon, Supabase, and Xata configuration.
npx claudepluginhub cameronapak/bknd-expert --plugin bknd-research-skillsThis skill uses the workspace's default tool permissions.
Set up and configure a production database for your Bknd application.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
Set up and configure a production database for your Bknd application.
| Database | Best For | Platform Compatibility | Cost |
|---|---|---|---|
| SQLite File | VPS, Docker, single-server | Node.js, Bun | Free |
| LibSQL/Turso | Serverless, edge, global | All platforms | Free tier |
| Cloudflare D1 | Cloudflare Workers | Cloudflare only | Free tier |
| PostgreSQL | Complex queries, transactions | VPS, Docker | Self-hosted |
| Neon | Serverless Postgres | Vercel, Lambda | Free tier |
| Supabase | Postgres + extras | Any | Free tier |
| Xata | Serverless + search | Any | Free tier |
Best for: Single-server deployments with full control
// bknd.config.ts
export default {
app: (env) => ({
connection: {
url: env.DB_URL ?? "file:data.db", // Relative to cwd
},
}),
};
# Relative path (project directory)
DB_URL=file:data.db
# Absolute path (recommended for production)
DB_URL=file:/var/data/myapp/bknd.db
mkdir -p /var/data/myapp
# docker-compose.yml
services:
bknd:
volumes:
- bknd-data:/app/data
environment:
- DB_URL=file:/app/data/bknd.db
volumes:
bknd-data:
Best for: Serverless, edge deployments, global distribution
# macOS/Linux
curl -sSfL https://get.tur.so/install.sh | bash
# Authenticate
turso auth login
# Create database
turso db create my-bknd-db
# Optional: Specify region
turso db create my-bknd-db --location lax # Los Angeles
# Get connection URL
turso db show my-bknd-db --url
# Output: libsql://my-bknd-db-username.turso.io
# Create auth token
turso db tokens create my-bknd-db
# Output: eyJhbGciOi...
// bknd.config.ts
export default {
app: (env) => ({
connection: {
url: env.DB_URL, // libsql://...
authToken: env.DB_TOKEN,
},
}),
};
DB_URL=libsql://my-bknd-db-username.turso.io
DB_TOKEN=eyJhbGciOi...
Common regions: ams (Amsterdam), fra (Frankfurt), lax (LA), lhr (London), nrt (Tokyo), syd (Sydney)
turso db locations # List all regions
Best for: Cloudflare Workers deployments
wrangler d1 create my-bknd-db
Output:
Created D1 database 'my-bknd-db'
database_name = "my-bknd-db"
database_id = "abc123-def456-..."
name = "my-bknd-app"
main = "src/index.ts"
compatibility_date = "2024-01-01"
[[d1_databases]]
binding = "DB"
database_name = "my-bknd-db"
database_id = "abc123-def456-..."
// src/index.ts
import { hybrid, type CloudflareBkndConfig } from "bknd/adapter/cloudflare";
import { d1Sqlite } from "bknd/adapter/cloudflare";
export default hybrid<CloudflareBkndConfig>({
app: (env) => ({
connection: d1Sqlite({ binding: env.DB }),
isProduction: true,
}),
});
# List databases
wrangler d1 list
# Execute SQL (local dev)
wrangler d1 execute my-bknd-db --local --command "SELECT * FROM posts"
# Execute SQL (production)
wrangler d1 execute my-bknd-db --command "SELECT * FROM posts"
# Export backup
wrangler d1 backup create my-bknd-db
Best for: Complex queries, large datasets, existing Postgres infrastructure
npm install postgres
# or
npm install pg
Using postgres (recommended):
import { PostgresJsConnection } from "bknd/adapter/postgres";
export default {
app: (env) => ({
connection: new PostgresJsConnection({
connectionString: env.DATABASE_URL,
}),
}),
};
Using pg:
import { PgPostgresConnection } from "bknd/adapter/postgres";
export default {
app: (env) => ({
connection: new PgPostgresConnection({
connectionString: env.DATABASE_URL,
}),
}),
};
DATABASE_URL=postgresql://user:password@host:5432/database?sslmode=require
Best for: Vercel, serverless, auto-scaling Postgres
npm install kysely-neon
import { createCustomPostgresConnection } from "bknd";
import { NeonDialect } from "kysely-neon";
const neon = createCustomPostgresConnection("neon", NeonDialect);
export default {
app: (env) => ({
connection: neon({
connectionString: env.NEON_DATABASE_URL,
}),
}),
};
NEON_DATABASE_URL=postgres://user:password@ep-xxx.us-east-1.aws.neon.tech/neondb?sslmode=require
Best for: Full-featured Postgres with extras (auth, storage, realtime)
Use "Direct connection" (not pooler) for Bknd:
postgresql://postgres:[PASSWORD]@db.[PROJECT-REF].supabase.co:5432/postgres
export default {
app: (env) => ({
connection: {
url: env.SUPABASE_DB_URL,
},
}),
};
SUPABASE_DB_URL=postgresql://postgres:your-password@db.abcdefgh.supabase.co:5432/postgres
Best for: Serverless Postgres with built-in search
npm install @xata.io/kysely
import { createCustomPostgresConnection } from "bknd";
import { XataDialect } from "@xata.io/kysely";
const xata = createCustomPostgresConnection("xata", XataDialect);
export default {
app: (env) => ({
connection: xata({
apiKey: env.XATA_API_KEY,
workspace: "your-workspace",
database: "your-database",
}),
}),
};
After configuring your database, Bknd auto-syncs schema on first request. For manual control:
# Dry run (preview changes)
npx bknd sync --dry-run
# Apply changes
npx bknd sync
# Force sync (use with caution)
npx bknd sync --force
// test-connection.ts
import { app } from "bknd";
const bknd = app({
connection: {
url: process.env.DB_URL!,
authToken: process.env.DB_TOKEN,
},
});
async function test() {
await bknd.build();
console.log("Connection successful!");
console.log("Entities:", Object.keys(bknd.modules.data.entities));
process.exit(0);
}
test().catch((e) => {
console.error("Connection failed:", e);
process.exit(1);
});
Run:
npx tsx test-connection.ts
Problem: Can't connect to database
Fix:
Problem: Missing or invalid auth token
Fix:
# Generate new token
turso db tokens create my-bknd-db
# Set in environment
export DB_TOKEN="eyJhbGciOi..."
Problem: env.DB is undefined in Cloudflare Workers
Fix: Check wrangler.toml binding name matches code:
[[d1_databases]]
binding = "DB" # Must match env.DB
Problem: Connection fails without SSL
Fix: Add ?sslmode=require to connection string:
DATABASE_URL=postgresql://user:pass@host:5432/db?sslmode=require
Problem: Database not created
Fix:
# Turso
turso db create my-bknd-db
# D1
wrangler d1 create my-bknd-db
# PostgreSQL
createdb my-bknd-db
Problem: Migrations fail on production database
Fix:
# Preview changes first
npx bknd sync --dry-run
# If stuck, use --force (data loss possible!)
npx bknd sync --force --drop
# SQLite
sqlite3 data.db .dump > backup.sql
# Using API
curl http://localhost:3000/api/data/posts > posts.json
# Via seed function (recommended)
# See bknd-seed-data skill
# Direct SQL (SQLite to SQLite only)
cat backup.sql | turso db shell my-bknd-db
DO:
DON'T:
--force --drop without backups