.agents/skills/bknd-database-provision/SKILL.md
Use when setting up a production database for Bknd. Covers SQLite file, LibSQL/Turso, Cloudflare D1, PostgreSQL, Neon, Supabase, and Xata configuration.
npx skillsauth add cameronapak/cultivate-fellowship bknd-database-provisionInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
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:[email protected]/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:[email protected]: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 backupsdevelopment
Use btca (Better Context App) to efficiently query and learn from the bknd backend framework. Use when working with bknd for (1) Understanding data module and schema definitions, (2) Implementing authentication and authorization, (3) Setting up media file handling, (4) Configuring adapters (Node, Cloudflare, etc.), (5) Learning from bknd source code and examples, (6) Debugging bknd-specific issues
development
Use when configuring webhook integrations in Bknd. Covers receiving incoming webhooks via HTTP triggers, sending outgoing webhooks with FetchTask, event-triggered webhooks on data changes, signature verification, retry patterns, and async processing.
development
Use when encountering Bknd errors, getting error messages, something not working, or needing quick fixes. Covers error code reference, quick solutions, and common mistake patterns.
tools
Use when writing tests for Bknd applications, setting up test infrastructure, creating unit/integration tests, or testing API endpoints. Covers in-memory database setup, test helpers, mocking, and test patterns.