Deploy to Cloudflare
Cloudflare is a natural fit when your stack already lives there: Workers run the app at the edge, R2 provides zero-egress object storage for media, and D1 or Turso cover the database. It takes more setup than Vercel, but the pieces compose well.
Next.js apps run on Cloudflare Workers via the OpenNext Cloudflare adapter (
@opennextjs/cloudflare). Cloudflare Pages' older Next.js support is not the recommended path - use Workers.
1. Pick your services
| Concern | Cloudflare-native choice | Alternative |
|---|---|---|
| Runtime | Workers (via OpenNext) | - |
| Database | D1 (SQLite at the edge) | Turso (libSQL) or hosted Postgres |
| Media | R2 (S3-compatible) | any S3-compatible store |
- Database - ChaiBuilder ships database adapters for D1 and libSQL/Turso alongside Postgres, so all three work. Turso or Postgres keep you portable across hosts; D1 keeps everything inside your Cloudflare account.
- Media - R2 speaks the S3 API, so the standard
storage configuration applies: set
S3_ENDPOINTto your R2 endpoint and leaveS3_REGIONat itsautodefault.
2. Add the OpenNext adapter
In your project:
pnpm add @opennextjs/cloudflare
Follow the adapter's setup to add its build command and a wrangler.jsonc with your Worker
name, compatibility date (with the nodejs_compat flag), and bindings for R2/D1 if you use
them. The adapter builds your existing Next.js app into a Worker - your application code
does not change.
3. Configure environment
Set the same variables as any other target - DATABASE_URL, PAYLOAD_SECRET,
CHAIBUILDER_APP_KEY, SITE_URL, the S3/R2 credentials, and CHAIBUILDER_LICENSE_KEY
after the trial. On Workers, put non-secret values in wrangler.jsonc vars and secrets in
wrangler secret put (or the dashboard). Full reference:
Environment & License.
# R2 as the media store
BUCKET_NAME=your-bucket
AWS_ACCESS_KEY_ID=…
AWS_SECRET_ACCESS_KEY=…
S3_REGION=auto
S3_ENDPOINT=https://<account-id>.r2.cloudflarestorage.com
4. Deploy
pnpm run build # or the adapter's preview/deploy scripts
npx opennextjs-cloudflare build
npx opennextjs-cloudflare deploy
Then verify the same three things as on any target: the site and builder load, publishing a page updates it without a redeploy, and an uploaded image lands in your R2 bucket.
Caching on Workers
The SSG + ISR model needs a cache backend on Workers. The OpenNext adapter provides incremental cache implementations (backed by R2 or KV) - enable one in the adapter config so first-visit page builds are cached and publish-time invalidation works. See Caching & Revalidation for what the app expects from the cache layer.
Notes and limits
- Workers runtime - Workers is not a full Node.js; the
nodejs_compatflag covers the APIs the app needs, but native binaries behave differently than on a server. Image processing (sharp) is the usual suspect - verify uploads and resizes early in your testing. - Bundle size - the builder is a large app; if you hit Worker size limits, check the adapter's documentation for code-splitting options and consider your plan's limits.
- Verify against your starter version - Cloudflare's Next.js support moves quickly. Treat the OpenNext adapter's docs as the source of truth for adapter config, and this page as the ChaiBuilder-specific overlay.
Related
- Storage Configuration - R2 setup details.
- Database Setup - Turso and Postgres connections.
- Hosting Overview - compare with Vercel and Node.

