
bknd-database-provision
by cameronapak
A no-build, un-bloated stack built upon Web Standards that feels freeing to use and can be deployed anywhere.
SKILL.md
name: bknd-database-provision description: Use when setting up a production database for Bknd. Covers SQLite file, LibSQL/Turso, Cloudflare D1, PostgreSQL, Neon, Supabase, and Xata configuration.
Provision Production Database
Set up and configure a production database for your Bknd application.
Prerequisites
- Bknd application with schema defined
- Account on chosen database provider (for cloud databases)
- Environment for storing connection credentials
When to Use UI Mode
- Creating databases via provider dashboards (Turso, Neon, Cloudflare, Supabase)
- Managing database settings and access tokens
- Viewing database metrics and logs
When to Use Code Mode
- Configuring database connection in Bknd
- CLI commands for database creation
- Schema sync and migrations
Database Selection Guide
| 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 |
SQLite File (VPS/Docker)
Best for: Single-server deployments with full control
Step 1: Configure Connection
// bknd.config.ts
export default {
app: (env) => ({
connection: {
url: env.DB_URL ?? "file:data.db", // Relative to cwd
},
}),
};
Step 2: Set Environment Variable
# Relative path (project directory)
DB_URL=file:data.db
# Absolute path (recommended for production)
DB_URL=file:/var/data/myapp/bknd.db
Step 3: Ensure Directory Exists
mkdir -p /var/data/myapp
Docker Volume
# docker-compose.yml
services:
bknd:
volumes:
- bknd-data:/app/data
environment:
- DB_URL=file:/app/data/bknd.db
volumes:
bknd-data:
LibSQL / Turso
Best for: Serverless, edge deployments, global distribution
Step 1: Install Turso CLI
# macOS/Linux
curl -sSfL https://get.tur.so/install.sh | bash
# Authenticate
turso auth login
Step 2: Create Database
# Create database
turso db create my-bknd-db
# Optional: Specify region
turso db create my-bknd-db --location lax # Los Angeles
Step 3: Get Connection Details
# 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...
Step 4: Configure Bknd
// bknd.config.ts
export default {
app: (env) => ({
connection: {
url: env.DB_URL, // libsql://...
authToken: env.DB_TOKEN,
},
}),
};
Step 5: Set Environment Variables
DB_URL=libsql://my-bknd-db-username.turso.io
DB_TOKEN=eyJhbGciOi...
Turso Locations
Common regions: ams (Amsterdam), fra (Frankfurt), lax (LA), lhr (London), nrt (Tokyo), syd (Sydney)
turso db locations # List all regions
Cloudflare D1
Best for: Cloudflare Workers deployments
Step 1: Create D1 Database
wrangler d1 create my-bknd-db
Output:
Created D1 database 'my-bknd-db'
database_name = "my-bknd-db"
database_id = "abc123-def456-..."
Step 2: Configure wrangler.toml
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-..."
Step 3: Configure Bknd Adapter
// 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,
}),
});
D1 CLI Commands
# 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
PostgreSQL (Self-Hosted)
Best for: Complex queries, large datasets, existing Postgres infrastructure
Step 1: Install Adapter
npm install postgres
# or
npm install pg
Step 2: Configure Connection
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,
}),
}),
};
Step 3: Set Connection String
DATABASE_URL=postgresql://user:password@host:5432/database?sslmode=require
Neon (Serverless Postgres)
Best for: Vercel, serverless, auto-scaling Postgres
Step 1: Create Project at neon.tech
- Sign up at neon.tech
- Create new project
- Copy connection string from dashboard
Step 2: Install Neon Dialect
npm install kysely-neon
Step 3: Configure Connection
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,
}),
}),
};
Step 4: Set Environment Variable
NEON_DATABASE_URL=postgres://user:password@ep-xxx.us-east-1.aws.neon.tech/neondb?sslmode=require
Supabase
Best for: Full-featured Postgres with extras (auth, storage, realtime)
Step 1: Create Project at supabase.com
- Sign up at supabase.com
- Create new project
- Go to Settings > Database > Connection string
Step 2: Get Direct Connection String
Use "Direct connection" (not pooler) for Bknd:
postgresql://postgres:[PASSWORD]@db.[PROJECT-REF].supabase.co:5432/postgres
Step 3: Configure Connection
export default {
app: (env) => ({
connection: {
url: env.SUPABASE_DB_URL,
},
}),
};
Step 4: Set Environment Variable
SUPABASE_DB_URL=postgresql://postgres:your-password@db.abcdefgh.supabase.co:5432/postgres
Xata
Best for: Serverless Postgres with built-in search
Step 1: Create Database at xata.io
- Sign up at xata.io
- Create workspace and database
Step 2: Install Xata Dialect
npm install @xata.io/kysely
Step 3: Configure Connection
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",
}),
}),
};
Schema Sync
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
Connection Testing
Verify Connection
// 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
Common Pitfalls
"Connection refused" or "ECONNREFUSED"
Problem: Can't connect to database
Fix:
- Verify connection URL format
- Check firewall/security group rules
- Ensure database is running
- For cloud: verify IP allowlist includes your server
"Auth token required" (LibSQL/Turso)
Problem: Missing or invalid auth token
Fix:
# Generate new token
turso db tokens create my-bknd-db
# Set in environment
export DB_TOKEN="eyJhbGciOi..."
"D1 binding not found"
Problem: env.DB is undefined in Cloudflare Workers
Fix: Check wrangler.toml binding name matches code:
[[d1_databases]]
binding = "DB" # Must match env.DB
"SSL required" (PostgreSQL)
Problem: Connection fails without SSL
Fix: Add ?sslmode=require to connection string:
DATABASE_URL=postgresql://user:pass@host:5432/db?sslmode=require
"Unknown database" or "Database does not exist"
Problem: Database not created
Fix:
# Turso
turso db create my-bknd-db
# D1
wrangler d1 create my-bknd-db
# PostgreSQL
createdb my-bknd-db
Schema Sync Fails
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
Migration from Development
Export Development Data
# SQLite
sqlite3 data.db .dump > backup.sql
# Using API
curl http://localhost:3000/api/data/posts > posts.json
Import to Production
# Via seed function (recommended)
# See bknd-seed-data skill
# Direct SQL (SQLite to SQLite only)
cat backup.sql | turso db shell my-bknd-db
DOs and DON'Ts
DO:
- Use cloud databases (Turso, D1, Neon) for serverless
- Store credentials in environment variables
- Test connection before deploying
- Use SSL for PostgreSQL connections
- Keep auth tokens secure
- Enable backups for production data
DON'T:
- Use file-based SQLite in serverless/edge
- Hardcode credentials in source code
- Share auth tokens across environments
- Skip connection testing
- Use
--force --dropwithout backups - Expose database directly to internet (use Bknd API)
Related Skills
- bknd-deploy-hosting - Deploy to hosting platforms
- bknd-production-config - Production security settings
- bknd-env-config - Environment variable setup
- bknd-seed-data - Populate database with initial data
- bknd-local-setup - Local development (pre-production)
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
1ヶ月以内に更新
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon
