Documentation
Deployment

Cloudflare Workers

Complete guide to deploying your project on Cloudflare Workers

Cloudflare Workers is a serverless platform running at the network edge, offering extremely low latency and a generous free tier. This project supports deployment to Workers, but requires some additional configuration due to the Workers runtime constraints (3 MiB gzipped bundle size limit, no native node:fs, etc.).

Cloudflare Workers support is built into this project. The deployment path uses a dedicated Cloudflare build script and wrangler.jsonc.

Prerequisites

npm install -g wrangler
wrangler login

Deployment Process

Upload environment variables

Workers secrets are not read from .env files. You need to upload them to Cloudflare.

Create a JSON file with your secrets:

grep -v '^#' .env.production | grep '=' | sed 's/^\([^=]*\)=\(.*\)$/"\1": "\2"/' | paste -sd',' | sed 's/^/{/' | sed 's/$/}/' > /tmp/secrets.json

Then bulk upload:

wrangler secret bulk /tmp/secrets.json
rm /tmp/secrets.json

Environment variables prefixed with VITE_ are embedded at build time and don't need to be uploaded as secrets. However, uploading them as secrets won't cause issues.

Build and Deploy

pnpm run deploy

This runs the Cloudflare build (pnpm run build:cf) followed by wrangler deploy. On success, you'll see the Worker URL:

Total Upload: ~13500 KiB / gzip: ~2330 KiB
Deployed vibe-any-tanstack triggers
  https://vibe-any-tanstack.<your-account>.workers.dev

Custom Domain

  1. Go to Cloudflare Dashboard → Workers & Pages → your Worker → Settings → Domains & Routes
  2. Click Add → Custom Domain
  3. Enter your domain (must be on Cloudflare DNS)

What Cloudflare Support Includes

FilePurpose
wrangler.jsoncWorkers config: name, compatibility date/flags, entry point
vite.config.tsCloudflare Vite plugin, SSR-only stubs, and Nitro bypass for Worker builds
package.jsonbuild:cf and deploy scripts
src/routes/sitemap[.]xml.tsRuntime sitemap generation without Node filesystem access

Bundle Size Optimizations

Workers has a 3 MiB gzipped limit on the free tier. The SSR stubs replace heavy client-only libraries with no-ops during the SSR build:

  • beautiful-mermaid, @streamdown/* → no-op stubs (removes ~2 MiB of Mermaid/Cytoscape)
  • shiki language grammars → empty stubs (saves ~500 KiB gzip)
  • @shikijs/engine-oniguruma → JavaScript regex engine (avoids WASM incompatibility)

These stubs only apply to the SSR bundle — the client-side code loads the full libraries normally.

Troubleshooting

View real-time logs

wrangler tail --format pretty

Check bundle size breakdown

wrangler deploy --dry-run --outdir .wrangler/dist

"Cannot access 'pg' before initialization"

This error means the pg (node-postgres) package is being used instead of postgres (postgres.js). The main branch already uses postgres.js, which is Workers-compatible. Make sure your feat/cloudflare branch is rebased on the latest main.

Bundle exceeds 3 MiB

If you add new heavy dependencies, you may need to add them to the ssrOnlyStubs() plugin in vite.config.ts, or convert them to dynamic imports.

On this page