Quickback Docs

Getting Started

Get started with Quickback in minutes. Learn how to define database tables with security configuration and compile them into a production-ready API.

Get started with Quickback in minutes. This guide shows you how to define a complete table with security configuration.

Install the CLI

npm install -g @kardoe/quickback

Create a Project

quickback create cloudflare my-app
cd my-app

This scaffolds a complete project with:

  • quickback.config.ts — Project configuration
  • definitions/features/ — Your table definitions
  • Example todos feature with full security configuration

Available templates:

  • cloudflare — Cloudflare Workers + D1 + Better Auth (free)
  • bun — Bun + SQLite + Better Auth (free)
  • turso — Turso/LibSQL + Better Auth (pro)

File Structure

Each table gets its own file with schema and config together using defineTable:

definitions/
└── features/
    └── rooms/
        ├── rooms.ts            # Table + security config
        ├── room-bookings.ts    # Related table + config
        ├── actions.ts          # Custom actions (optional)
        └── handlers/           # Action handlers (optional)
            └── activate.ts

Complete Example

Here's a complete rooms table with all security layers:

// definitions/features/rooms/rooms.ts
import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';
import { defineTable } from '@quickback/compiler';

export const rooms = sqliteTable('rooms', {
  id: text('id').primaryKey(),
  name: text('name').notNull(),
  description: text('description'),
  capacity: integer('capacity').notNull().default(10),
  roomType: text('room_type').notNull(),
  isActive: integer('is_active', { mode: 'boolean' }).notNull().default(true),
  deactivationReason: text('deactivation_reason'),

  // Ownership - required for firewall data isolation
  organizationId: text('organization_id').notNull(),
});

export default defineTable(rooms, {
  // 1. FIREWALL - Data isolation
  firewall: { organization: {} },

  // 2. GUARDS - Field modification rules
  guards: {
    createable: ["name", "description", "capacity", "roomType"],
    updatable: ["name", "description", "capacity"],
    protected: {
      isActive: ["activate", "deactivate"],  // Only via actions
    },
  },

  // 3. CRUD - Role-based access control
  crud: {
    list: { access: { roles: ["owner", "admin", "member"] }, pageSize: 25 },
    get: { access: { roles: ["owner", "admin", "member"] } },
    create: { access: { roles: ["owner", "admin"] } },
    update: { access: { roles: ["owner", "admin"] } },
    delete: { access: { roles: ["owner", "admin"] }, mode: "soft" },
  },
});

export type Room = typeof rooms.$inferSelect;

What Each Layer Does

  1. Firewall: Automatically adds WHERE organizationId = ? to every query. Users in Org A can never see Org B's data.
  2. Guards: Controls which fields can be modified — createable for POST, updatable for PATCH, protected for action-only fields.
  3. CRUD Access: Role-based access control for each operation. Members can read, only admins can write.

Compile and Run

# Log in (first time only)
quickback login

# Compile your definitions
quickback compile

# Run locally
npm run dev

Generated Endpoints

Quickback generates these endpoints from the example above:

MethodEndpointDescription
GET/api/v1/roomsList rooms (owners, admins, members)
GET/api/v1/rooms/:idGet single room
POST/api/v1/roomsCreate room (admins only)
PATCH/api/v1/rooms/:idUpdate room (admins only)
DELETE/api/v1/rooms/:idSoft delete room (admins only)

Next Steps

On this page