# Hand-Crafted Setup

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 @quickback-dev/cli`

## 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
└── ...
```

```bash
mkdir -p quickback/features
```

### 2. Write Your Config

Create `quickback/quickback.config.ts`:

```typescript
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](/compiler/config/providers) for all options.

### 3. Create Your First Feature

Create a feature directory with a schema + security definition:

```bash
mkdir quickback/features/candidates
```

Create `quickback/features/candidates/candidates.ts`:

```typescript
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: [{ field: 'organizationId', equals: 'ctx.activeOrgId' }],
  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"] } },
  },
  read: {
    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

```bash
quickback login
quickback compile
```

The 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:

```typescript
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 using `defineTable()` (required)
- **`actions.ts`** — Custom actions using `defineActions()` (optional)

## Adding Features

To add a new feature, create a new directory under `quickback/features/` and recompile:

```bash
mkdir quickback/features/jobs
# Create jobs/jobs.ts with defineTable(...)
quickback compile
```

The compiler detects all features automatically — no registration needed.

## Recompiling

After any change to your definitions, recompile to regenerate the output:

```bash
quickback compile
```

The 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](/compiler/config) — All config options
- [Schema definitions](/compiler/definitions/schema) — Define tables with `defineTable()`
- [Security pillars](/compiler/definitions) — Firewall, Access, Guards, Masking
- [Templates](/compiler/getting-started/templates) — Use a template for new projects instead
