Providers
Runtime, database, auth, and storage provider options for quickback.config.ts.
Providers configure which services your compiled backend targets.
Runtime Providers
| Provider | Description |
|---|---|
cloudflare | Cloudflare Workers (Hono) |
bun | Bun runtime (Hono) |
node | Node.js runtime (Hono) |
import { defineRuntime } from "@quickback/compiler";
providers: {
runtime: defineRuntime("cloudflare"),
}Database Providers
| Provider | Description |
|---|---|
cloudflare-d1 | Cloudflare D1 (SQLite) |
better-sqlite3 | SQLite via better-sqlite3 (Bun/Node) |
libsql | LibSQL / Turso |
neon | Neon (PostgreSQL) |
supabase | Supabase (PostgreSQL) |
import { defineDatabase } from "@quickback/compiler";
providers: {
database: defineDatabase("cloudflare-d1", {
generateId: "prefixed", // "uuid" | "cuid" | "nanoid" | "prefixed" | "serial" | false
namingConvention: "snake_case", // "camelCase" | "snake_case"
usePlurals: false, // Auth table names: "users" vs "user"
}),
}Database Options
| Option | Type | Default (D1) | Description |
|---|---|---|---|
generateId | string | false | "prefixed" | ID generation strategy |
namingConvention | string | "snake_case" | Column naming convention |
usePlurals | boolean | false | Pluralize auth table names (e.g. user vs users) |
splitDatabases | boolean | true | Separate auth and features databases |
authBinding | string | "AUTH_DB" | Binding name for auth database |
featuresBinding | string | "DB" | Binding name for features database |
databaseId | string | — | D1 database ID for the features database (used in generated wrangler.toml) |
authDatabaseId | string | — | D1 database ID for the auth database |
featuresDatabaseId | string | — | Explicit features DB ID (falls back to databaseId) |
filesDatabaseId | string | — | D1 database ID for the files metadata database |
webhooksDatabaseId | string | — | D1 database ID for the webhooks database |
Setting Database IDs for Deployment
When deploying to production, set your D1 database IDs so the compiler generates a ready-to-deploy wrangler.toml:
providers: {
database: defineDatabase("cloudflare-d1", {
authDatabaseId: "fe6c77c4-2131-40be-a8fc-3649eef2a38c",
databaseId: "bba22981-cb6e-43d6-bf32-4193513c60b1",
filesDatabaseId: "c3b8866b-cc4f-4e51-8382-0af244584d93",
}),
}If these are omitted, the compiler uses local-dev placeholders and you'll need to manually edit wrangler.toml before deploying.
usePlurals only affects auth tables generated by Better Auth (e.g. user vs users, session vs sessions). Feature table names come directly from your Drizzle schema definitions — whatever you pass to sqliteTable() or pgTable() is used as-is. The namingConvention setting applies to both auth and feature column names.
ID Generation Options
| Value | Description | Example |
|---|---|---|
"uuid" | Server generates UUID | 550e8400-e29b-41d4-a716-446655440000 |
"cuid" | Server generates CUID | clh2v8k9g0000l508h5gx8j1a |
"nanoid" | Server generates nanoid (21-char, URL-safe) | V1StGXR8_Z5jdHi6B-myT |
"short" | 6-char alphanumeric (nanoid customAlphabet) | a3F9xK |
"prefixed" | Prefixed ID from table name | room_abc123 |
"serial" | Database auto-increments | 1, 2, 3 |
false | Client provides ID (enables PUT/upsert) | Any string |
"short" produces IDs with ~56.8 billion possible values (62^6). That's fine for small/scoped tables like rooms, invites, or share codes — but at roughly 238,000 rows you hit a 50% chance of collision (birthday bound). Don't use it for high-volume records. "nanoid" and "short" both require the nanoid package in your project.
Auth Providers
| Provider | Description |
|---|---|
better-auth | Better Auth with plugins |
supabase-auth | Supabase Auth |
external | External auth via Cloudflare service binding |
import { defineAuth } from "@quickback/compiler";
providers: {
auth: defineAuth("better-auth", {
session: {
expiresInDays: 7,
updateAgeInDays: 1,
},
rateLimit: {
enabled: true,
window: 60,
max: 100,
},
}),
}Better Auth Options
| Option | Type | Description |
|---|---|---|
session.expiresInDays | number | Session expiration in days |
session.updateAgeInDays | number | Session refresh interval in days |
rateLimit.enabled | boolean | Enable rate limiting |
rateLimit.window | number | Rate limit window in seconds |
rateLimit.max | number | Max requests per window |
socialProviders | object | Social login providers (google, github, discord) |
debugLogs | boolean | Enable auth debug logging |
Auth table naming (usePlurals, namingConvention) is inherited from your database provider config — you don't need to set it separately on the auth provider. usePlurals controls whether auth tables are named user/session or users/sessions. It does not affect feature tables, which use whatever name you define in your schema.
Better Auth Plugins
When features: ["organizations"] is set in your config, the compiler automatically enables organization-related plugins. Additional plugins can be configured:
| Plugin | Description |
|---|---|
organization | Multi-tenant organizations |
admin | Admin panel access |
apiKey | API key authentication |
anonymous | Anonymous sessions |
upgradeAnonymous | Convert anonymous to full accounts |
twoFactor | Two-factor authentication |
passkey | WebAuthn passkey login |
magicLink | Email magic link login |
emailOtp | Email one-time password |
deviceAuthorization | Device auth flow (CLI tools) |
jwt | JWT token support |
openAPI | OpenAPI spec generation |
Storage Providers
import { defineStorage, defineFileStorage } from "@quickback/compiler";
providers: {
storage: defineStorage("kv", {
binding: "KV_STORE",
namespaceId: "7ed0f824a8c54c388713d9fdf63cd004",
}),
fileStorage: defineFileStorage("r2", {
binding: "FILES",
maxFileSize: "10mb",
allowedTypes: ["image/png", "image/jpeg", "application/pdf"],
publicDomain: "files.example.com",
}),
}The KV namespaceId can be set on the storage provider config, or as kvId on the auth provider config (since KV is primarily used for auth sessions). The compiler checks both locations.
Storage Types
| Type | Description |
|---|---|
kv | Key-value storage (Cloudflare KV, Redis) |
r2 | Object storage (Cloudflare R2) |
memory | In-memory storage (development only) |
redis | Redis storage |
File Storage Options
| Option | Type | Description |
|---|---|---|
binding | string | R2 bucket binding name |
maxFileSize | string | Maximum file size (e.g. "10mb") |
allowedTypes | string[] | Allowed MIME types |
publicDomain | string | Public domain for file URLs |
userScopedBuckets | boolean | Scope files by user |