Why Migrate from Vercel to Cloudflare Pages?
Vercel is the default choice for Next.js deployment โ it's made by the same team. But as your app grows, the costs grow fast. Cloudflare Pages offers a compelling alternative with generous free limits and global edge performance at a fraction of the price.
๐ Korean migration guide with full screenshots: Next.js๋ฅผ Vercel์์ Cloudflare๋ก ์ด์ ํ๊ธฐ
Vercel vs Cloudflare Pages: Cost Comparison
| Vercel (Pro) | Cloudflare Pages | |
|---|---|---|
| Price | $20/month | Free / $5/month |
| Bandwidth | 1 TB included | Unlimited |
| Build minutes | 6,000/month | 500/month (free) |
| Serverless requests | 1M included | 100K/day free |
| Edge locations | ~100 PoPs | 300+ PoPs |
| Cold starts | Occasional | Near-zero (V8 isolates) |
The verdict on cost: A mid-traffic app with serverless functions can cost $50-200/month on Vercel Pro. The same app often runs free on Cloudflare Pages + Workers.
What Works on Cloudflare Pages
Next.js on Cloudflare uses the @cloudflare/next-on-pages adapter. As of 2026, it supports:
- โ App Router & Pages Router
- โ Static pages (SSG)
- โ Server-side rendering (SSR) via Edge Runtime
- โ API routes as Cloudflare Workers
- โ
Image optimization (with
next/imageon edge) - โ Middleware
- โ Environment variables
- โ ๏ธ Node.js APIs โ limited (must use Edge Runtime)
- โ
fsmodule, native Node.js modules
Step-by-Step Migration
Step 1: Add the Cloudflare Adapter
npm install -D @cloudflare/next-on-pages
Step 2: Update next.config.js
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
// Required for Cloudflare Pages
};
export default nextConfig;
Step 3: Add wrangler.toml
name = "my-nextjs-app"
compatibility_date = "2024-01-01"
compatibility_flags = ["nodejs_compat"]
pages_build_output_dir = ".vercel/output/static"
Step 4: Update package.json scripts
{
"scripts": {
"build": "next build",
"pages:build": "npx @cloudflare/next-on-pages",
"preview": "npm run pages:build && wrangler pages dev",
"deploy": "npm run pages:build && wrangler pages deploy"
}
}
Step 5: Switch API routes to Edge Runtime
// app/api/hello/route.ts
export const runtime = 'edge'; // Add this line
export async function GET() {
return Response.json({ message: 'Hello from Cloudflare Edge!' });
}
Step 6: Deploy to Cloudflare Pages
# Login to Cloudflare
npx wrangler login
# Build and deploy
npm run deploy
Or connect your GitHub repo directly in the Cloudflare Dashboard โ Pages โ Create a project.
Common Issues and Fixes
Issue 1: Node.js module not found
Error: Module not found: Can't resolve 'crypto'
Fix: Use the Web Crypto API instead:
// Instead of Node's crypto:
const hash = await crypto.subtle.digest('SHA-256', data);
Issue 2: Dynamic imports failing
Add compatibility_flags = ["nodejs_compat"] to your wrangler.toml.
Issue 3: Environment variables not loading
In Cloudflare Dashboard โ Pages โ Settings โ Environment variables, add your vars for both Production and Preview environments.
Performance Comparison (Real Numbers)
After migrating a Next.js blog (50k monthly visits):
| Metric | Vercel | Cloudflare Pages |
|---|---|---|
| TTFB (p50) | 180ms | 45ms |
| TTFB (p95) | 420ms | 90ms |
| Monthly cost | $47 | $0 |
| Build time | 2m 10s | 3m 40s |
Cloudflare's V8 isolate cold start is near-zero vs Vercel's Lambda-based functions.
When to Stay on Vercel
Cloudflare Pages isn't always the right choice:
- You heavily use ISR (Incremental Static Regeneration) โ partial support only
- Your app uses Node.js-specific libraries that can't run on the edge
- You need advanced Vercel features like preview comments, speed insights, or their analytics dashboard
- Your team is non-technical and values Vercel's DX polish
Conclusion
For most Next.js apps โ especially content-heavy sites, blogs, and API-light applications โ Cloudflare Pages is a cost-effective, high-performance alternative to Vercel.
The migration takes about 2-4 hours. The savings can be immediate.
Full Korean guide with screenshots, troubleshooting, and edge cases:
๐ Next.js๋ฅผ Vercel์์ Cloudflare Pages๋ก ์ด์ ํ๊ธฐ โ 2026 ์์ ๊ฐ์ด๋
Top comments (0)