GET STARTED
Hand Crafted
Write your definitions by hand. Understand exactly how Quickback works - one file at a time.
Project Structure
A Quickback project has three parts: your config, your feature definitions, and the compiled output. You only write the first two.
my-app/
├── quickback/
│ ├── quickback.config.ts # Target, database, auth config
│ └── features/
│ ├── todos/
│ │ ├── todos.ts # Schema + security (defineTable)
│ │ └── actions.ts # Business logic (never overwritten)
│ └── invoices/
│ ├── invoices.ts # Schema + security
│ └── actions.ts # approve(), reject(), etc.
├── src/ # Compiled output (generated)
├── drizzle/ # Migrations (generated)
└── package.json The Definition File
Each feature has one defineTable() call that combines your Drizzle schema with all four security layers.
import { sqliteTable, text } from "drizzle-orm/sqlite-core";
import { defineTable } from "quickback";
// 1. Define your Drizzle schema
const todos = sqliteTable("todos", {
title: text("title").notNull(),
content: text("content"),
status: text("status")
.default("pending"),
});
// 2. Add security rules
export default defineTable(todos, {
firewall: { organization: { } },
guards: {
createable: ["title", "content"],
updatable: ["title", "content"],
protected: { status: ["complete"] },
},
masking: {
content: { roles: ["admin"] },
},
crud: {
list: { access: { roles: ["member"] } },
create: { access: { roles: ["member"] } },
update: { access: { roles: ["member"] } },
delete: { access: { roles: ["admin"] } },
},
views: {
summary: {
fields: ["id", "title", "status"],
access: { roles: ["member", "admin"] },
},
full: {
fields: ["id", "title", "content", "status"],
access: { roles: ["admin"] },
},
},
}); Firewall
Scopes every query to the user's organization. No data crosses tenant boundaries.
Guards
createable and updatable control which fields can be written. protected fields can only change via typed Actions.
Masking
Fields like content are only visible to specified roles. Everyone else sees a masked value.
CRUD + Access
Each operation (list, create, update, delete) is granted per-role. Deny by default - if it's not listed, it's blocked.
Views
Named field projections with role-based access. summary returns three fields for members; full returns everything for admins only.
Audit Fields
You don't define them. The compiler adds createdAt, createdBy, modifiedAt, modifiedBy, deletedAt automatically.
The Actions File
Actions are your custom business logic. They're never overwritten because they become part of the compiled output. Access controls and preconditions are enforced before your code runs.
import { z } from "zod";
export const actions = {
complete: {
description: "Mark todo as complete",
input: z.object({
completedNote: z.string().optional()
}),
access: {
roles: ["member", "admin"],
record: { status: { equals: "pending" } }
},
execute: async ({ db, ctx, record, input }) => {
// Your logic here
return {
status: "complete",
};
}
}
}; Role + record state verified before execute() runs
Zod schema validates request body automatically
Who ran it, what changed, when - recorded automatically
Compile & Ship
Once your definitions are ready, compile to your target and deploy.
Write definitions
Schema + security in todos.ts
Login
quickback login Compile
quickback compile Deploy
npx wrangler deploy $ quickback login
✓ Login successful! Using organization: Acme
$ quickback compile
✓ Found 2 features: todos, invoices
✓ Compiled firewall rules
✓ Compiled access policies
✓ Compiled guards
✓ Compiled masking rules
✓ Generated routes: 12 endpoints
✓ Generated migrations
✓ Output: src/
Ready to deploy. What Gets Generated
The src/ folder is your compiled output. Standard TypeScript you can read, debug, and extend.
API Routes
Hono routes with firewall middleware, access checks, guard enforcement, and masking applied.
Database Migrations
Drizzle migrations generated from your schema. Audit fields included automatically.
Auth Config
Better Auth configuration with org support, roles, passkeys, and session management.
Action Endpoints
POST routes for each action with access checks, input validation, and audit logging wired in.
View Endpoints
GET routes for each named view. Return only the fields you defined, with role checks and masking applied.
OpenAPI Docs
Auto-generated API documentation for every endpoint. Import into Postman or generate client SDKs.
Typed SDK
TypeScript client SDK with full type safety. Autocomplete for every endpoint and action.
Ready to Build?
Read the full documentation for detailed guides on every security layer, action patterns, and deployment options.