> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hookfish.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Cloudflare Workers

> Deploy Hookfish on Workers with PostgreSQL through Hyperdrive.

For production on Cloudflare Workers, use PostgreSQL through a Hyperdrive
binding. Hyperdrive supplies the connection string consumed by Hookfish's
PostgreSQL adapter and manages the underlying connection pool.

<Warning>
  The SQLite Durable Objects database adapter and the current
  `--backend cloudflare` scaffold are experimental. Use them for evaluation,
  not as the advised production storage path. Prefer Hyperdrive with
  PostgreSQL.
</Warning>

## Create the Worker

Start from the Cloudflare scaffold, then replace its Durable Objects database
configuration with Hyperdrive:

```bash theme={null}
pnpm dlx hookfish init my-broker --backend cloudflare
cd my-broker
```

Create a Hyperdrive configuration for your PostgreSQL database in the
Cloudflare dashboard, then add its ID to `wrangler.jsonc`:

```jsonc theme={null}
{
  "$schema": "./node_modules/wrangler/config-schema.json",
  "name": "my-broker",
  "main": "./src/index.ts",
  "compatibility_date": "2026-08-11",
  "compatibility_flags": ["nodejs_compat"],
  "observability": {
    "enabled": true
  },
  "hyperdrive": [
    {
      "binding": "HYPERDRIVE",
      "id": "<hyperdrive-id>"
    }
  ]
}
```

Remove the `durable_objects`, `exports`, and Durable Object migration entries
from the generated configuration.

## Configure the database binding

Replace `src/index.ts` with a Worker that resolves the Hyperdrive binding for
each request:

```ts theme={null}
import { HookfishServer } from '@hookfish/api'
import { postgres } from '@hookfish/database/postgres'
import {
  createGitHubProvider,
  createLinearProvider,
  createMcpProvider,
  createNotionProvider,
} from '@hookfish/providers'

const db = postgres<Env>(
  (env) => env.HYPERDRIVE.connectionString,
  {
    cache: false,
    fetchTypes: false,
    max: 5,
    prepare: true,
  },
)

const hookfish = await HookfishServer.init<Env>({
  db,
  includeSwagger: true,
  returnTo: 'https://dashboard.example.com',
  trustedOrigins: ['https://dashboard.example.com'],
  providerManagement: true,
  providers: (env) => ({
    github: createGitHubProvider({
      clientId: env.GITHUB_CLIENT_ID,
      clientSecret: env.GITHUB_CLIENT_SECRET,
    }),
    linear: createLinearProvider({
      clientId: env.LINEAR_CLIENT_ID,
      clientSecret: env.LINEAR_CLIENT_SECRET,
    }),
    mcp: createMcpProvider(),
    notion: createNotionProvider({
      clientId: env.NOTION_CLIENT_ID,
      clientSecret: env.NOTION_CLIENT_SECRET,
    }),
  }),
})

export default {
  fetch(request, env, context) {
    return hookfish.fetch(request, env, context)
  },
} satisfies ExportedHandler<Env>
```

`cache: false` prevents the adapter from retaining request-owned database
clients in module state. Hyperdrive manages the underlying pool. `max: 5`
stays below the Worker request's concurrent external-connection limit.

## Configure local PostgreSQL

Set the local connection string for the `HYPERDRIVE` binding, then generate
types and start Wrangler:

```bash theme={null}
export CLOUDFLARE_HYPERDRIVE_LOCAL_CONNECTION_STRING_HYPERDRIVE="postgres://user:password@127.0.0.1:5432/hookfish"
pnpm typegen
pnpm dev
```

Keep the real connection string out of source control and shell history. Local
Wrangler connects directly to PostgreSQL; Hyperdrive caching does not run in
local mode.

## Run migrations

Run Hookfish's bundled PostgreSQL migrations from CI or another trusted
environment that can connect directly to the database:

```ts theme={null}
import { migrateDatabase } from '@hookfish/database'
import { postgres } from '@hookfish/database/postgres'

const db = postgres(process.env.DATABASE_URL ?? '')
await migrateDatabase(db, process.env)
```

Do not run schema migrations through a user request or on every Worker startup.

## Store secrets and deploy

Use Wrangler's interactive secret prompts:

```bash theme={null}
pnpm exec wrangler secret put OAUTH_ENCRYPTION_KEY
pnpm exec wrangler secret put HOOKFISH_API_KEY
pnpm exec wrangler secret put GITHUB_CLIENT_ID
pnpm exec wrangler secret put GITHUB_CLIENT_SECRET
pnpm typecheck
pnpm deploy
```

After deployment, set `OAUTH_REDIRECT_BASE_URL` to the Worker's public HTTPS
origin and register the callback URLs reported by Hookfish.
