Skip to main content

Cloudflare Workers Deployment

vinext is built for Cloudflare Workers—zero cold starts, global edge deployment, and integrated platform services (KV, R2, D1, AI).

One-Command Deploy

The simplest way to deploy is using the built-in deploy command:
This command:
1

Detects Your Router

Automatically detects whether you’re using App Router or Pages Router and generates appropriate configuration.
2

Installs Dependencies

Checks for and installs required packages:
  • @cloudflare/vite-plugin (Workers integration)
  • wrangler (Cloudflare CLI)
  • @vitejs/plugin-rsc (App Router only)
3

Generates Config Files

Creates missing files if they don’t exist:
  • wrangler.jsonc - Workers configuration
  • vite.config.ts - Vite build config
  • worker/index.ts - Worker entry point
4

Fixes ESM Issues

Automatically:
  • Adds "type": "module" to package.json
  • Renames CJS config files to .cjs extension
  • Resolves path aliases from tsconfig.json
5

Builds and Deploys

Runs the Vite build and deploys to Cloudflare Workers using wrangler.

Deploy Options

Generated Configuration

wrangler.jsonc

The deploy command generates a complete Wrangler configuration:
Key Configuration:
  • main - Entry point for your Worker
  • assets - Serves static files (JS, CSS, images) with binding for programmatic access
  • images - Cloudflare Images binding for next/image optimization
  • compatibility_flags - Enables Node.js compatibility layer

Worker Entry (App Router)

For App Router projects, vinext generates worker/index.ts:

Worker Entry (Pages Router)

Vite Config (App Router)

Vite Config (Pages Router)

Image Optimization

vinext integrates with Cloudflare Images for edge image optimization:
Features:
  • Automatic format negotiation (AVIF, WebP, JPEG)
  • On-demand resizing
  • Quality optimization
  • CDN caching
The /_vinext/image endpoint handles all transformations using the Cloudflare Images binding.

Incremental Static Regeneration (ISR)

For apps using ISR, add a KV namespace to wrangler.jsonc:
Create a KV namespace:
Then configure the cache handler:

ISR Example

The page is:
  1. Rendered on first request and cached in KV
  2. Served from cache for 1 hour (stale-while-revalidate)
  3. Regenerated in the background after expiration
  4. Updated cache serves subsequent requests

Traffic-Aware Pre-Rendering (TPR)

Experimental: Pre-render only the pages that actually receive traffic.
TPR queries Cloudflare zone analytics at deploy time to find which pages get traffic, pre-renders only those, and uploads them to KV cache. Options:
Requirements:
  • Custom domain (zone analytics unavailable on *.workers.dev)
  • CLOUDFLARE_API_TOKEN with Zone.Analytics read permission
Benefits:
  • SSG-level latency for popular pages
  • No full-site pre-rendering
  • Automatic based on real traffic data

Environment Variables

Build-Time Variables

NEXT_PUBLIC_* variables are inlined at build time:

Runtime Variables (Secrets)

For sensitive data, use Wrangler secrets:
Access in your Worker:
Or via wrangler.toml for non-sensitive values:

Platform Bindings

Access Cloudflare platform services via environment bindings:

KV (Key-Value Storage)

D1 (SQLite Database)

R2 (Object Storage)

Custom Domains

Add a custom domain via Cloudflare Dashboard or wrangler:
Or in wrangler.toml:

Preview Deployments

Create preview deployments for testing:
Preview deployments:
  • Get a unique URL (e.g., my-app-preview.workers.dev)
  • Don’t affect production
  • Can be tested before promoting to production

CI/CD with GitHub Actions

Monitoring and Logs

Real-Time Logs

Stream logs from your Worker in real-time.

Analytics Dashboard

View metrics in the Cloudflare Dashboard:
  • Request volume
  • Error rates
  • CPU time per request
  • Geographic distribution
  • Cache hit ratios

Custom Logging

Logs appear in wrangler tail and the Cloudflare dashboard.

Troubleshooting

Authentication Error

Error: Authentication error during deploy Solution: Generate a Cloudflare API token:
  1. Go to https://dash.cloudflare.com/profile/api-tokens
  2. Click “Create Token”
  3. Use the “Edit Cloudflare Workers” template
  4. Set the token:

Worker Size Exceeded

Error: Worker size exceeds limit Solution: Workers have a 1 MB limit after compression. Reduce bundle size:
  • Remove unused dependencies
  • Use dynamic imports for large libraries
  • Check bundle size with rollup-plugin-visualizer

Native Modules Error

Error: Error: Cannot find module 'sharp' or similar Solution: Native Node.js modules can’t run in Workers. vinext auto-stubs common ones (sharp, resvg, satori), but if you encounter others:
Create empty-stub.js:

ISR Not Working

Problem: Pages aren’t being cached Solution: Verify:
  1. KV namespace is created and bound in wrangler.jsonc
  2. Cache handler is configured with setCacheHandler()
  3. Routes have revalidate set (App Router) or return revalidate from getStaticProps (Pages Router)

Performance

vinext on Cloudflare Workers delivers:
  • Cold starts: 0ms (Workers have no cold starts)
  • TTFB: 10-50ms globally (edge execution)
  • Bundle size: 20-30% smaller than Next.js
  • Build time: ~2x faster than Next.js
See live benchmarks at benchmarks.vinext.workers.dev

Next Steps

Configuration Guide

Advanced configuration and customization

ISR and Caching

Learn about caching strategies

Examples

Explore working example deployments

Workers Documentation

Official Cloudflare Workers docs