#Cloudflare Workers Deployment
The cloudflare build target generates a Cloudflare Workers bundle with a wrangler.jsonc configuration.
#Build
alepha build --target=cloudflare
This forces the workerd runtime. You cannot combine --target=cloudflare with --runtime=node or --runtime=bun.
#Environment Variables
Required for deployment:
| Variable | Description |
|---|---|
CLOUDFLARE_ACCOUNT_ID |
Your Cloudflare account ID |
CLOUDFLARE_API_TOKEN |
API token with Workers permissions |
#Deploy
alepha deploy detects the wrangler.jsonc in dist/ and runs Wrangler:
alepha build --target=cloudflare
alepha deploy
If Wrangler is not installed, the deploy command installs it automatically as a dev dependency.
#Local Testing
Test the Worker locally before deploying:
wrangler dev --config=dist/wrangler.jsonc
#Generated Configuration
The build produces:
dist/wrangler.jsonc-- Wrangler configuration with worker name, compatibility flags, and bindingsdist/main.cloudflare.js-- Worker entry point that bootstraps Alepha and handlesfetch,scheduled, andqueueevents
The wrangler.jsonc includes nodejs_compat compatibility flag and no_bundle: true (Alepha bundles the code itself).
#SQLite D1
Use Cloudflare D1 for the database. Set the DATABASE_URL in .env.production:
DATABASE_URL=d1://my-database:00000000-0000-0000-0000-000000000000
Format: d1://<database-name>:<database-id>
The build automatically adds the D1 binding to wrangler.jsonc:
1{2 "d1_databases": [{3 "binding": "my-database",4 "database_name": "my-database",5 "database_id": "00000000-0000-0000-0000-000000000000"6 }]7}
#R2 Buckets
If your application uses $bucket with CloudflareR2Provider, the R2 binding is added to wrangler.jsonc automatically.
#Cron Triggers
$scheduler cron expressions are detected at build time and mapped to Cloudflare Cron Triggers in wrangler.jsonc:
1{2 "triggers": {3 "crons": ["0 * * * *", "0 0 * * *"]4 }5}
The Worker's scheduled handler dispatches the cloudflare:scheduled event, which Alepha routes to the matching $scheduler handler.
#Build with Mode
Use --mode to control which .env file is loaded:
alepha build --target=cloudflare --mode production
This loads .env and .env.production before building.
#Static Assets
If your project has a React frontend, the built client assets are placed in dist/public/ and served via Cloudflare's asset binding.
#Queue
$queue and $job are supported via Cloudflare Queues. The build automatically adds the JOBS_QUEUE binding and queue consumer to wrangler.jsonc when queue primitives are detected.
At runtime, CloudflareQueueProvider replaces the default queue provider and WorkerdWorkerProvider handles message consumption via push-based queue events (no polling).
#Jobs without a queue (direct mode)
Cloudflare Queues are powerful but overkill for low-volume apps. By default, $job falls back to direct mode when AlephaApiJobsQueue is not loaded:
push()writes a row to the outbox table, then schedules the handler in-process so the HTTP response returns immediately.- If the worker invocation ends before the handler finishes, the next reconciliation sweep re-dispatches the row.
This is the recommended default on Cloudflare Workers when you don't want a Queues binding. Add .with(AlephaApiJobsQueue) only when you need a real queue.
#Retry granularity
$job retries are sweep-driven on every platform — there's no exponential backoff. When a handler fails, the row is marked scheduled with scheduledAt = now, and the next sweep tick (configured by jobConfig.sweepCron, default */5 * * * *) picks it up.
Practically this means:
- A job retried 3 times can take up to ~15 minutes total to fail terminally.
- The first retry can happen anywhere between a few seconds and ~5 minutes after the failure, depending on when the next sweep tick fires.
- If you need tighter retry latency, lower
sweepCronin yourjobConfigatom.
This is identical on Node, Docker, and Cloudflare — no platform-specific timing surprises.
#Limitations
- Redis-based features (
$lockwith Redis,$cachewith Redis,$topicwith Redis) are not available
#Configuration
1import { defineConfig } from "alepha/cli/config"; 2 3export default defineConfig({ 4 build: { 5 target: "cloudflare", 6 cloudflare: { 7 config: { 8 // Additional wrangler.jsonc fields merged into the generated config 9 },10 },11 },12});
#Full Example
# .env.production
DATABASE_URL=d1://alepha-app:00000000-0000-0000-0000-000000000000
# Build and deploy
alepha build --target=cloudflare --mode production
alepha deploy