Configuration
Reference for quickback.config.ts — project name, template, features, providers, and compiler options.
The quickback.config.ts file configures your Quickback project. It defines which providers to use, which features to enable, and how the compiler generates code.
import { defineConfig, defineRuntime, defineDatabase, defineAuth } from "@quickback/compiler";
export default defineConfig({
name: "my-app",
template: "hono",
features: { organizations: true },
providers: {
runtime: defineRuntime("cloudflare"),
database: defineDatabase("cloudflare-d1"),
auth: defineAuth("better-auth"),
},
});Required Fields
| Field | Type | Description |
|---|---|---|
name | string | Project name |
template | "hono" | Application template ("nextjs" is experimental) |
providers | object | Runtime, database, and auth provider configuration |
Optional Fields
| Field | Type | Description |
|---|---|---|
features | object | Feature flags — see Single-Tenant Mode |
build | object | Build options (outputDir, packageManager, dependencies) |
compiler | object | Compiler options (including migration rename hints for headless CI) |
openapi | object | OpenAPI spec generation (generate, publish) — see OpenAPI |
schemaRegistry | object | Schema registry generation for the CMS (enabled by default, { generate: false } to disable) — see Schema Registry |
etag | object | ETag caching for GET responses (enabled by default, { enabled: false } to disable) — see Caching & ETags |
cms | boolean | object | Embed CMS in compiled Worker — see CMS |
account | boolean | object | Embed Account UI in compiled Worker — see Account UI |
trustedOrigins | string[] | CORS trusted origins for cross-domain auth |
domain | string | Primary API domain (auto-inferred from custom domains if not set) |
dev | object | Local development settings (port) |
auth | object | App-level auth settings (roleHierarchy) — see Access |
email | object | Email delivery config (provider, from, fromName) |
Custom Dependencies
Add third-party npm packages to the generated package.json using build.dependencies. This is useful when your action handlers import external libraries.
export default defineConfig({
name: "my-app",
template: "hono",
build: {
dependencies: {
"fast-xml-parser": "^4.5.0",
"lodash-es": "^4.17.21",
},
},
providers: {
runtime: defineRuntime("cloudflare"),
database: defineDatabase("cloudflare-d1"),
auth: defineAuth("better-auth"),
},
});These are merged into the generated package.json alongside Quickback's own dependencies. Run npm install after compiling to install them.
Headless Migration Rename Hints
When drizzle-kit generate detects a potential rename, it normally prompts for confirmation. Cloud/CI compiles are non-interactive, so you must provide explicit rename hints.
Add hints in compiler.migrations.renames:
export default defineConfig({
// ...
compiler: {
migrations: {
renames: {
// Keys are NEW names, values are OLD names
tables: {
events_v2: "events",
},
columns: {
events: {
summary_text: "summary",
},
},
},
},
},
});Rules:
tables:new_table_name -> old_table_namecolumns.<table>:new_column_name -> old_column_name- Keys must match the names in your current schema (the new names)
- Validation fails fast for malformed rename config, unsupported keys, or conflicting legacy/new rename paths.
Security Contract Reports and Signing
After generation, Quickback verifies machine-checkable security contracts for Hono routes and RLS SQL.
It also emits a report artifact and signature artifact by default:
reports/security-contracts.report.jsonreports/security-contracts.report.sig.json
You can configure output paths and signing behavior:
export default defineConfig({
// ...
compiler: {
securityContracts: {
failMode: "error", // or "warn"
report: {
path: "reports/security-contracts.report.json",
signature: {
enabled: true,
required: true,
keyEnv: "QUICKBACK_SECURITY_REPORT_SIGNING_KEY",
keyId: "prod-k1",
path: "reports/security-contracts.report.sig.json",
},
},
},
},
});If signature.required: true and no key is available, compilation fails with a clear error message (or warning in failMode: "warn").
CMS Configuration
Embed the Quickback CMS in your compiled Worker. The CMS reads your schema registry and renders a complete admin interface — zero UI code per table.
// Simple — embed CMS at root
cms: true,
// With custom domain
cms: { domain: "cms.example.com" },
// With access control (only admins can access CMS)
cms: { domain: "cms.example.com", access: "admin" },| Option | Type | Default | Description |
|---|---|---|---|
domain | string | — | Custom domain for CMS. Adds a custom_domain route to wrangler.toml. |
access | "user" | "admin" | "user" | Controls who can access the CMS. When "admin", only users with user.role === "admin" can enter — enforced at the Worker level (SPA shell, /api/v1/schema, and custom_view CRUD all return 403 to non-admins) and in the SPA. Also hides the CMS link in Account UI. See CMS Connecting for the full enforcement model. |
Account UI Configuration
Embed the Account UI in your compiled Worker. Provides login, signup, profile management, organization management, and admin — all built from your config at compile time.
// Simple — embed Account UI with defaults
account: true,
// Full configuration
account: {
domain: "auth.example.com",
adminDomain: "admin.example.com",
name: "My App",
companyName: "My Company",
auth: {
password: true,
emailOTP: false,
passkey: true,
organizations: true,
admin: true,
},
},| Option | Type | Description |
|---|---|---|
domain | string | Custom domain for Account UI (e.g., auth.example.com) |
adminDomain | string | Custom domain for admin-only access (e.g., admin.example.com). Serves the same Account SPA — the client-side router handles admin routing. |
name | string | App display name shown on login, profile, and email templates |
companyName | string | Company name for branding |
tagline | string | App tagline shown on login page |
description | string | App description |
Auth Feature Flags
Control which authentication features are included in the Account UI bundle. Disabled features are excluded at compile time — their routes are removed before the Vite build, keeping bundle sizes minimal.
| Flag | Type | Default | Description |
|---|---|---|---|
auth.password | boolean | true | Email/password authentication |
auth.emailOTP | boolean | false | Email one-time password login |
auth.passkey | boolean | false | WebAuthn/FIDO2 passkey authentication |
auth.signup | boolean | true | Self-service account registration |
auth.organizations | boolean | false | Multi-tenant organization management (dashboard, invitations, roles) |
auth.admin | boolean | false | Admin panel for user management (requires Better Auth admin plugin) |
auth.emailVerification | boolean | false | Require email verification after signup |
Trusted Origins
List of origins allowed to make cross-origin requests to your API. Required when your CMS, Account UI, or frontend app run on different domains.
trustedOrigins: [
"https://auth.example.com",
"https://admin.example.com",
"https://cms.example.com",
"https://app.example.com",
],Local Development
Configure local development URLs. These are automatically added to the trusted origins list for CORS and Better Auth, so authentication works out of the box during local development.
dev: {
port: 8787, // wrangler dev port (default: 8787)
api: "http://localhost:8787", // API backend URL
cms: "http://localhost:8787/cms", // CMS URL (path on same worker)
account: "http://localhost:8787/account", // Account URL (path on same worker)
},If you run a SPA standalone on its own Vite dev server, set its URL here so CORS allows it:
dev: {
port: 8787,
api: "http://localhost:8787",
account: "http://localhost:5173", // standalone Account dev server
},| Field | Type | Default | Description |
|---|---|---|---|
port | number | 8787 | Local dev server port (sets [dev].port in wrangler.toml) |
api | string | http://localhost:{port} | API backend URL |
cms | string | — | CMS dev URL (added to trusted origins if set) |
account | string | — | Account dev URL (added to trusted origins if set) |
Email Configuration
Configure email delivery for authentication emails (verification, password reset, invitations).
// Cloudflare Email Service (default) — uses send_email binding, no API keys needed
email: {
from: "noreply@example.com",
fromName: "My App",
},
// AWS SES — requires AWS credentials set as Wrangler secrets
email: {
provider: "aws-ses",
region: "us-east-2",
from: "noreply@example.com",
fromName: "My App",
},| Field | Type | Default | Description |
|---|---|---|---|
provider | "cloudflare" | "aws-ses" | "cloudflare" | Email transport |
from | string | "noreply@example.com" | Sender email address |
fromName | string | "{name} | Account Services" | Sender display name |
region | string | "us-east-2" | AWS SES region (aws-ses only) |
Multi-Domain Example
A complete config with CMS, Account UI, and Admin on separate subdomains:
export default {
name: "my-app",
template: "hono",
cms: { domain: "cms.example.com", access: "admin" },
account: {
domain: "auth.example.com",
adminDomain: "admin.example.com",
name: "My App",
companyName: "Example Inc.",
auth: {
password: true,
emailOTP: false,
passkey: true,
organizations: false,
admin: true,
},
},
email: {
from: "noreply@example.com",
fromName: "My App",
},
trustedOrigins: [
"https://auth.example.com",
"https://admin.example.com",
"https://cms.example.com",
"https://example.com",
],
providers: {
runtime: { name: "cloudflare", config: {
routes: [{ pattern: "api.example.com", custom_domain: true }],
}},
database: { name: "cloudflare-d1", config: { binding: "DB" } },
auth: { name: "better-auth", config: { plugins: ["admin"] } },
},
};This produces a single Cloudflare Worker serving five domains. See Multi-Domain Architecture for details on hostname routing, cross-subdomain cookies, and the unified fallback domain.
See the sub-pages for detailed reference on each section:
- Providers — Runtime, database, and auth options
- Variables — Environment variables and flags
- Output — Generated file structure
- Single-Tenant Mode — Admin-only and public-facing apps without organizations
- Multi-Domain Architecture — Custom domains, hostname routing, and cross-subdomain auth