Loading...
Loading...
Use when setting up a production database for Bknd. Covers SQLite file, LibSQL/Turso, Cloudflare D1, PostgreSQL, Neon, Supabase, and Xata configuration.
npx skill4agent add cameronapak/bknd-skills bknd-database-provision| 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 |
// 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.dbmkdir -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:# 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...amsfralaxlhrnrtsydturso db locations # List all regionswrangler d1 create my-bknd-dbCreated 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-dbnpm install postgres
# or
npm install pgpostgresimport { PostgresJsConnection } from "bknd/adapter/postgres";
export default {
app: (env) => ({
connection: new PostgresJsConnection({
connectionString: env.DATABASE_URL,
}),
}),
};pgimport { 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=requirenpm install kysely-neonimport { 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=requirepostgresql://postgres:[PASSWORD]@db.[PROJECT-REF].supabase.co:5432/postgresexport default {
app: (env) => ({
connection: {
url: env.SUPABASE_DB_URL,
},
}),
};SUPABASE_DB_URL=postgresql://postgres:your-password@db.abcdefgh.supabase.co:5432/postgresnpm install @xata.io/kyselyimport { 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",
}),
}),
};# 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);
});npx tsx test-connection.ts# Generate new token
turso db tokens create my-bknd-db
# Set in environment
export DB_TOKEN="eyJhbGciOi..."env.DB is undefined[[d1_databases]]
binding = "DB" # Must match env.DB?sslmode=requireDATABASE_URL=postgresql://user:pass@host:5432/db?sslmode=require# Turso
turso db create my-bknd-db
# D1
wrangler d1 create my-bknd-db
# PostgreSQL
createdb my-bknd-db# 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--force --drop