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.).

The Cloudflare Workers deployment uses a dedicated branch (feat/cloudflare) that includes necessary Vite plugins and Workers config on top of main. Make sure you are working on this branch.

Prerequisites

npm install -g wrangler
wrangler login

Deployment Process

Switch to the Cloudflare branch

The feat/cloudflare branch contains the necessary Vite plugins (ssrOnlyStubs, shikiNoWasm) and wrangler.jsonc config. Keep this branch rebased on main.

git checkout feat/cloudflare
git rebase main

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 vite build 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 AddCustom Domain
  3. Enter your domain (must be on Cloudflare DNS)

What the feat/cloudflare Branch Changes

Only two files differ from main:

FilePurpose
wrangler.jsoncWorkers config: name, compatibility date/flags, entry point
vite.config.tsThree additions: ssrOnlyStubs() plugin, shikiNoWasm() plugin, and conditional cloudflare() Vite plugin

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