~ 4 min read
How to Deploy a Next.js App to Cloudflare Workers
Recently I went through and deployed a Next.js app on Cloudflare workers. It is configured with their CI/CD so it instantly deploys on every push to my main branch on GitHub. It found it a painful process to go through and I thought I’d document everything that I learned here in order to save devs (including future me) the pain that I experienced. Hopefully it will save some of you the several days that I lost to discovering all this stuff by myself.
Open Next
First up, elephant in the room. Why wouldn’t you use Vercel to do this? Next.js is built by them, surely they’ll be the best at hosting it?
Well, as you might not be aware, there is a lot of horror stories in using Vercel. In fact there’s a website dedicated to serverless horrors where they frequently appear. I urge you to check some of these out if you haven’t already - typically they end in a huge bill. I didn’t really want to get locked into vercel only, or get any surprises so decided to try out Open Next. Open Next is a movement to better enable portability of Next.js apps to a platform of choice. It’s backed by Cloudflare, SST and Netlify and worth checking out. I have a fair amount of domains with Cloudflare and their free plans for workers are quite liberal so decided to go with them.
Setup
Firstly I needed to install workers and the wrangler cli to my existing app (you can use this command to create a Next.js project if you dont have one already):
pnpm install @opennextjs/cloudflare@latest
pnpm install --save-dev wrangler@latest
This givens you a number of commands to make it easy to publish to cloudflare workers. You’ll also need a wrangler/open next config file - but these will be generated if you run the build process itself.
These assume you’ll only ever be publishing from the cli and not within their CI/CD, so I also added the build-open command to be run there.
"build": "next build",
"build-open": "opennextjs-cloudflare build",
"preview": "opennextjs-cloudflare build && opennextjs-cloudflare preview",
"deploy": "opennextjs-cloudflare build && opennextjs-cloudflare deploy",
"upload": "opennextjs-cloudflare build && opennextjs-cloudflare upload",
"cf-typegen": "wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts",
Once that is done you can then run that command to generate the wranger/open next config files and check your project linting.
pnpm run build-open
process.env
Your wrangler.jsonc file should be configured with a compatibility date of Apr, 1 2025 or later like so:
{...
"compatibility_date": "2025-04-01"
...}
This is super important since this was when process.env population was made a default. If it’s set earlier it will be empty (unless you explicitly set the nodejs_compat flag) you’ll find you won’t be able to read from it within workers without messing about with a shim and wonder where your environment variables are! You can read more about that here. Annoyingly, the open next cloudflare docs use an earlier date in their wrangler example. I lost a lot of time to this 😢.
Worker Setup
To set up your worker, first create a repo on github (or your preffered git host) and push up your existing project. Then step through the worker setup under compute in cloudflare using the repo you created. When you get to the build settings, configure them like so:
Build command: pnpm run build-open
Deploy command: pnpx wrangler deploy
Then attempt to build your project. If all went well, you should find your Next.js app is deployed.
I found the workers ci/cd interface on Cloudflare really difficult to locate builds or retry them. Currently, there’s seemingly no way to reach build details from an individual project interface and you can only do so from the “Workers & Pages” list. This is marked as “Beta” right now so I hope it improves over time.
My example code of a simple shadcn project deployed in this way is available here.