Hand-Crafted Setup
Add Quickback definitions to an existing project without using a template.
If you have an existing project and want to add Quickback-generated API endpoints, you can set up the definitions directory manually instead of using a template.
Prerequisites
- An existing Hono-based project (Cloudflare Workers or Bun)
- Node.js 18+ or Bun installed
- The Quickback CLI:
npm install -g @kardoe/quickback
Setup
1. Create the Quickback Directory
Create a quickback/ directory in your project root with the following structure:
your-project/
├── quickback/
│ ├── quickback.config.ts
│ └── features/
│ └── (your features go here)
├── src/ # Your existing code
├── package.json
└── ...mkdir -p quickback/features2. Write Your Config
Create quickback/quickback.config.ts:
import { defineConfig } from "@quickback/compiler";
export default defineConfig({
name: "my-app",
template: "hono",
features: ["organizations"],
providers: {
runtime: { name: "cloudflare", config: {} },
database: {
name: "cloudflare-d1",
config: { binding: "DB" },
},
auth: { name: "better-auth", config: {} },
},
});Adjust the providers to match your existing stack. See Providers for all options.
3. Create Your First Feature
Create a feature directory with a schema + security definition:
mkdir quickback/features/candidatesCreate quickback/features/candidates/candidates.ts:
import { sqliteTable, text } from "drizzle-orm/sqlite-core";
import { defineTable } from "@quickback/compiler";
export const candidates = sqliteTable("candidates", {
id: text("id").primaryKey(),
name: text("name").notNull(),
email: text("email").notNull(),
phone: text("phone"),
source: text("source"),
organizationId: text("organization_id").notNull(),
});
export default defineTable(candidates, {
firewall: {
organization: {},
},
guards: {
createable: ["name", "email", "phone", "source"],
updatable: ["name", "phone"],
},
masking: {
email: { type: "email", show: { roles: ["hiring-manager", "recruiter"] } },
phone: { type: "phone", show: { roles: ["hiring-manager", "recruiter"] } },
},
crud: {
list: { access: { roles: ["owner", "hiring-manager", "recruiter", "interviewer"] } },
get: { access: { roles: ["owner", "hiring-manager", "recruiter", "interviewer"] } },
create: { access: { roles: ["owner", "hiring-manager", "recruiter"] } },
update: { access: { roles: ["owner", "hiring-manager", "recruiter"] } },
delete: { access: { roles: ["owner", "hiring-manager"] }, mode: "soft" },
},
});4. Log In and Compile
quickback login
quickback compileThe compiler generates a complete src/ directory with route handlers, middleware, database schemas, and migrations.
5. Integrate with Your Existing Code
The compiled output creates a self-contained Hono app in src/index.ts. If you need to integrate the generated routes into an existing Hono app, you can import the feature routes directly:
import { Hono } from "hono";
import candidatesRoutes from "./features/candidates/routes";
const app = new Hono();
// Your existing routes
app.get("/", (c) => c.json({ status: "ok" }));
// Mount generated feature routes
app.route("/api/v1/candidates", candidatesRoutes);
export default app;Directory Structure
The compiler expects this structure inside quickback/:
quickback/
├── quickback.config.ts # Required: compiler configuration
└── features/ # Required: feature definitions
├── candidates/
│ ├── candidates.ts # Schema + security (defineTable)
│ └── actions.ts # Optional: custom actions
├── jobs/
│ ├── jobs.ts
│ └── actions.ts
└── ...Each feature directory should contain:
{name}.ts— The main definition file usingdefineTable()(required)actions.ts— Custom actions usingdefineActions()(optional)
Adding Features
To add a new feature, create a new directory under quickback/features/ and recompile:
mkdir quickback/features/jobs
# Create jobs/jobs.ts with defineTable(...)
quickback compileThe compiler detects all features automatically — no registration needed.
Recompiling
After any change to your definitions, recompile to regenerate the output:
quickback compileThe compiler regenerates the entire src/ directory. Your definitions in quickback/ are the source of truth — never edit the generated files directly.
Warning: Don't edit files in src/ manually. They will be overwritten on the next compile. All changes should be made in your quickback/ definitions.
Next Steps
- Configuration reference — All config options
- Schema definitions — Define tables with
defineTable() - Security pillars — Firewall, Access, Guards, Masking
- Templates — Use a template for new projects instead