Quick Facts
- Category: Networking
- Published: 2026-05-02 06:06:31
- OpenAI Smartphone Project Confirmed: Exclusive Details on the AI Giant’s Hardware Ambitions
- Strawberry Music Player Emerges as Leading Linux Music Management Solution
- How to Navigate Tech Company Opposition to State Online Safety Regulations
- Python 3.15.0 Alpha 5 Released: What's New and Next
- Amazon S3 Files: Bridging Object Storage and File System Access for High-Performance Workloads
Introduction
When building modern web applications with Next.js 14 (App Router) and Supabase for authentication and Postgres, the default deployment platform is often Vercel. And for good reason—it offers an excellent developer experience. However, after running the same project on both platforms for about a week, I discovered that Cloudflare Workers can deliver lower latency (especially TTFB) and a more flexible free tier. Historically, deploying Next.js on Cloudflare was tricky—earlier solutions like Cloudflare Pages struggled with full Next.js features, and tools like next-on-pages often lagged behind. That changed with @opennextjs/cloudflare, which compiles a standard Next.js application into a Cloudflare Worker, supporting SSR, ISR, middleware, and the Image component without requiring major code changes. This guide walks you through the exact steps I used to deploy my full-stack Next.js + Supabase application to Cloudflare Workers, with automated CI/CD via GitHub Actions. It’s the runbook I wish I had when I started.

What You Need
- A Next.js 14 project (App Router) with Supabase integration
- Node.js 18+ installed locally
- A Cloudflare account (free tier works)
- A GitHub repository for your project
- Basic familiarity with terminal commands
Step-by-Step Deployment Guide
Step 1: Install the Cloudflare Adapter
Start by adding the @opennextjs/cloudflare package to your project. This adapter compiles your Next.js app into a Cloudflare Worker. Run:
npm install @opennextjs/cloudflareThen, create or update your next.config.js to include the adapter:
const withOpenNext = require('@opennextjs/cloudflare/config');
module.exports = withOpenNext({
// your existing Next.js config
});This step is crucial—it hooks the build process to generate a worker-compatible bundle.
Step 2: Wire OpenNext into next dev
To maintain a smooth local development experience, you need to run the Next.js dev server through OpenNext. Modify your package.json scripts:
"scripts": {
"dev": "opennext dev",
"build": "opennext build",
"start": "opennext start"
}Now, npm run dev will use the OpenNext development server, which simulates the Cloudflare Workers environment locally. This ensures your app behaves as expected before deployment.
Step 3: Local Environment Setup with .dev.vars
Cloudflare Workers use environment variables via secrets. For local development, create a .dev.vars file at the project root. This file holds local equivalents of your production secrets, such as Supabase URL and anon key. Example:
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=your-anon-key
Important: Add .dev.vars to your .gitignore to avoid pushing secrets to version control. In your app, you can access these via process.env.SUPABASE_URL.
Step 4: Deploy Your App from Your Local Machine
Before setting up CI/CD, test a manual deployment. First, install the Cloudflare Wrangler CLI:
npm install -g wranglerLog in to your Cloudflare account:
wrangler loginThen build and deploy:
npm run build
npx wrangler deployThis will create a worker named after your project (you can rename it in wrangler.toml). After successful deployment, Wrangler outputs your worker URL. Visit it to verify your app runs.
Step 5: Push Your Secrets to the Worker
Your Supabase keys and other sensitive data must be stored as Cloudflare Worker secrets, not hardcoded. Use Wrangler to set each secret:
wrangler secret put SUPABASE_URL
wrangler secret put SUPABASE_ANON_KEYYou’ll be prompted to enter the value. Repeat for all secrets your app needs. These are encrypted and only accessible to the worker at runtime.
Step 6: Set Up Continuous Deployment with GitHub Actions
Automate deployments so that every push to your main branch triggers a build and deploy. Create the file .github/workflows/deploy.yml in your repository with the following content:
name: Deploy to Cloudflare Workers
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 18
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Deploy to Cloudflare Workers
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
You need to create a Cloudflare API token with Workers Scripts:Edit permission, and add it as a GitHub secret named CF_API_TOKEN. Also add your Supabase secrets as GitHub secrets (e.g., SUPABASE_URL, SUPABASE_ANON_KEY) so the action can set them on the worker. To do that, extend the workflow to set secrets using wrangler secret put commands, or use environment variables in the Wrangler action. A cleaner approach: use wrangler secret bulk with a JSON file. For brevity, the above action assumes secrets are already set manually once. After initial setup, each push will automatically deploy the latest code.
Step 7: Daily Workflow – Updating the Project
Once CI/CD is running, your daily workflow is simple:
- Pull the latest changes from
main. - Create a feature branch, make changes, and commit.
- Push the branch and open a pull request.
- After merging to
main, GitHub Actions automatically builds and deploys to Cloudflare Workers. - Monitor deployment status via the Actions tab.
If you need to update secrets, do so manually via wrangler secret put or update GitHub secrets and rerun the workflow.
Tips & Best Practices
- Watch out for Node.js APIs: Cloudflare Workers use V8 isolates, which lack full Node.js support (e.g.,
fs,child_process). If your app relies on those, you may need to refactor or use Cloudflare’s compatibility flags. - Use
.dev.varswisely: Keep it in sync with your production secrets to avoid surprises. - Optimize cold starts: While Workers have near-zero cold starts, complex middleware can still cause delays. Keep middleware lightweight.
- Leverage Cloudflare bindings: For image optimization, use the IMAGES binding instead of Next.js built-in image optimization to reduce costs.
- Monitor usage: The free tier is generous, but check your dashboard for request counts and bandwidth to avoid unexpected limits.
- Test locally with wrangler dev: Before deploying, run
npx wrangler devto simulate the Cloudflare environment and catch issues early.
Deploying Next.js on Cloudflare Workers is now as smooth as on Vercel, thanks to OpenNext. With this guide, you can enjoy lower latency, minimal cold starts, and cost-effective scaling—all with automated CI/CD via GitHub Actions.