Quickback Docs

Empty Scaffolding Templates

Start from scratch with just the config file. Available for Cloudflare Workers and Bun.

The empty templates create a project with only the configuration file — no example features. Use these when you know exactly what you want to build and don't need starter code.

Available Empty Templates

TemplateRuntimeDatabaseCommand
emptyCloudflare WorkersD1quickback create empty my-app
empty-bunBunbetter-sqlite3quickback create empty-bun my-app

Alias: quickback create scaffold my-app (same as empty)

Create the Project

# Cloudflare Workers
quickback create empty my-app

# Bun / local development
quickback create empty-bun my-app

This scaffolds a minimal project:

my-app/
├── quickback/
│   ├── quickback.config.ts       # Compiler configuration
│   └── features/                 # Empty — add your own
├── package.json
└── tsconfig.json

Generated Configuration

Cloudflare (empty)

export default {
  name: "my-app",
  template: "hono",
  features: {
    organizations: true,
  },
  providers: {
    runtime: { name: "cloudflare", config: {} },
    database: {
      name: "cloudflare-d1",
      config: { binding: "DB" },
    },
    auth: { name: "better-auth", config: {} },
  },
};

Bun (empty-bun)

export default {
  name: "my-app",
  template: "hono",
  features: {
    organizations: true,
  },
  providers: {
    runtime: { name: "bun", config: {} },
    database: {
      name: "better-sqlite3",
      config: { path: "./data/app.db" },
    },
    auth: { name: "better-auth", config: {} },
  },
};

Both use multi-tenant mode (organizations: true) by default. Change to organizations: false for single-tenant mode.

Adding Your First Feature

Create a feature directory with a schema file:

mkdir -p quickback/features/products
// quickback/features/products/products.ts
import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";
import { defineTable } from "@quickback/compiler";

export const products = sqliteTable("products", {
  id: text("id").primaryKey(),
  name: text("name").notNull(),
  description: text("description"),
  price: integer("price").notNull(),
  organizationId: text("organization_id").notNull(),
  ownerId: text("owner_id").notNull(),
});

export default defineTable(products, {
  firewall: {
    organization: {},
    owner: { mode: "optional" },
  },
  guards: {
    createable: ["name", "description", "price"],
    updatable: ["name", "description", "price"],
  },
  crud: {
    list: { access: { roles: ["owner", "admin", "member"] } },
    get: { access: { roles: ["owner", "admin", "member"] } },
    create: { access: { roles: ["owner", "admin"] } },
    update: { access: { roles: ["owner", "admin"] } },
    delete: { access: { roles: ["owner", "admin"] }, mode: "soft" },
  },
});

Then compile:

quickback login    # First time only
quickback compile

Setup Steps

Follow the same setup steps as the full templates:

The only difference is you'll need to add at least one feature before compiling.

Next Steps

On this page