Cloudflare Next.js Deployment Skill
Deploy Next.js applications to Cloudflare Workers using the OpenNext Cloudflare adapter for production-ready serverless Next.js hosting.
When to Load References
Load additional reference files based on your specific task:
-
references/error-catalog-extended.md- Load when encountering ANY error during setup, build, or deployment. Contains complete catalog of 11+ documented issues with root causes, solutions, and official sources. -
references/service-integration-patterns.md- Load when integrating Cloudflare services (D1, R2, KV, Workers AI) with Next.js. Contains complete patterns for database queries, file uploads, caching, and AI inference. -
references/troubleshooting.md- Load for general troubleshooting and debugging guidance beyond the error catalog. -
references/feature-support.md- Load when checking if a specific Next.js feature is supported on Cloudflare Workers (e.g., "Can I use Server Actions?", "Does ISR work?"). -
references/database-client-example.ts- Load when integrating external database clients (Drizzle, Prisma, PostgreSQL, MySQL) with proper request-scoping patterns required by Workers. -
references/open-next.config.ts- Load when configuring caching behavior, image optimization, or custom OpenNext settings. -
references/package.json- Load when setting up a new project or migrating an existing Next.js application to Cloudflare Workers. -
references/wrangler.jsonc- Load when configuring Worker settings, compatibility flags, environment bindings (D1, R2, KV, AI), or deployment options.
Use This Skill When
- Deploying Next.js applications (App Router or Pages Router) to Cloudflare Workers
- Need server-side rendering (SSR), static site generation (SSG), or incremental static regeneration (ISR) on Cloudflare
- Migrating existing Next.js apps from Vercel, AWS, or other platforms to Cloudflare
- Building full-stack Next.js applications with Cloudflare services (D1, R2, KV, Workers AI)
- Need React Server Components, Server Actions, or Next.js middleware on Workers
- Want global edge deployment with Cloudflare's network
Key Differences from Standard Next.js
OpenNext Adapter transforms Next.js builds for Workers. Critical requirements:
- Node.js runtime (NOT Edge) via
nodejs_compatflag - Request-scoped database clients (global clients fail)
- Worker size limits: 3 MiB (free) / 10 MiB (paid)
- Dual testing:
next devfor speed,previewfor production-like validation
Setup Patterns
New Project Setup
Use Cloudflare's create-cloudflare (C3) CLI to scaffold a new Next.js project pre-configured for Workers:
npm create cloudflare@latest -- my-next-app --framework=next
What this does:
- Runs Next.js official setup tool (
create-next-app) - Installs
@opennextjs/cloudflareadapter - Creates
wrangler.jsoncwith correct configuration - Creates
open-next.config.tsfor caching configuration - Adds deployment scripts to
package.json - Optionally deploys immediately to Cloudflare
Development workflow:
npm run dev # Next.js dev server (fast reloads)
npm run preview # Test in workerd runtime (production-like)
npm run deploy # Build and deploy to Cloudflare
Existing Project Migration
To add the OpenNext adapter to an existing Next.js application:
1. Install the adapter
bun add -d @opennextjs/cloudflare
Secure Installation
Adapter packages handle production traffic — pin exact versions and audit before upgrading. Follow supply chain security best practices:
- Block post-install scripts —
npm config set ignore-scripts true(or Bun: disabled by default) - Cooldown period — Wait 7 days for new package versions to be vetted by the community
- Audit before installing — Run
socket package score npm <pkg>or usesocket npm install <pkg>to check packages
Load the dependency-upgrade skill for full security configuration including Socket CLI integration, cooldown setup, lockfile validation, and CI enforcement.
2. Create wrangler.jsonc
{
"name": "my-next-app",
"compatibility_date": "2025-05-05",
"compatibility_flags": ["nodejs_compat"]
}
Critical configuration:
compatibility_date: Minimum2025-05-05(for FinalizationRegistry support)compatibility_flags: Must includenodejs_compat(for Node.js runtime)
3. Create open-next.config.ts
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
export default defineCloudflareConfig({
// Caching configuration (optional)
// See: https://opennext.js.org/cloudflare/caching
});
4. Update package.json scripts
{
"scripts": {
"dev": "next dev",
"build": "next build",
"preview": "opennextjs-cloudflare build && opennextjs-cloudflare preview",
"deploy": "opennextjs-cloudflare build && opennextjs-cloudflare deploy",
"cf-typegen": "wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts"
}
}
Script purposes:
dev: Next.js development server (fast iteration)preview: Build + run in workerd runtime (test before deploy)deploy: Build + deploy to Cloudflarecf-typegen: Generate TypeScript types for Cloudflare bindings
5. Ensure Node.js runtime (not Edge)
Remove Edge runtime exports from your app:
// ❌ REMOVE THIS (Edge runtime not supported)
export const runtime = "edge";
// ✅ Use Node.js runtime (default)
// No export needed - Node.js is default
Development Workflow
Dual Testing Required:
npm run dev- Fast iteration (Next.js dev server)npm run preview- Production-like testing (workerd runtime, REQUIRED before deploy)npm run deploy- Build and deploy
Critical: Always test preview before deploying to catch Workers-specific runtime issues
Critical Configuration
wrangler.jsonc minimum requirements:
{
"compatibility_date": "2025-05-05", // Minimum for FinalizationRegistry
"compatibility_flags": ["nodejs_compat"] // Required for Node.js runtime
}
Cloudflare Bindings: Add D1, R2, KV, or AI bindings in wrangler.jsonc, access via process.env (see "Cloudflare Services Integration" section for complete patterns)
Package Exports (if needed): Create .env with WRANGLER_BUILD_PLATFORM="node" to prioritize Node.js exports
Top 5 Critical Errors
These are the most common deployment-blocking errors. For the complete catalog of 11+ errors, load references/error-catalog-extended.md.
1. Worker Size Limit Exceeded
Error: "Your Worker exceeded the size limit of 3 MiB" (Free) or "10 MiB" (Paid)
Quick Fix: Upgrade plan, analyze bundle with bunx opennextjs-cloudflare build → check .open-next/server-functions/default/handler.mjs.meta.json, remove unused dependencies, or use dynamic imports.
Source: https://opennext.js.org/cloudflare/troubleshooting#worker-size-limits
2. Cannot Perform I/O on Behalf of Different Request
Error: "Cannot perform I/O on behalf of a different request"
Cause: Global database client reused across requests (Workers limitation)
Quick Fix: Create database clients INSIDE request handlers, never globally. Or use Cloudflare D1 which is designed for Workers.
// ❌ WRONG: Global client
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
// ✅ CORRECT: Request-scoped
export async function GET() {
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
// ... use pool
await pool.end();
}
3. NPM Package Import Failures
Error: "Could not resolve '<package>'"
Quick Fix: Enable nodejs_compat flag in wrangler.jsonc, and/or create .env with WRANGLER_BUILD_PLATFORM="node".
**Source