Migrating Next.js 16 from Vercel to Cloudflare: Overcoming the 25MB Limit
21 December 2025

Infrastructure migration is simply the process of moving your application’s hosting environment to a different provider to leverage specific benefits like edge performance or cost efficiency.
Now, almost all Next.js applications run seamlessly on Vercel. However, to reduce infrastructure costs, we decided to move from Vercel’s managed AWS environment to Cloudflare.
In this article, I will take you through the specific challenges I encountered during this migration with a Next.js 16 application. I will exemplify exactly how I debugged the ‘Edge Runtime’ constraints and the dreaded bundle size limit.
We would take a look at two key technical hurdles: replacing Node.js SDKs and forcing Webpack optimisation on a base level in the sense of how it actually relates to getting your build under the strict 25MB limit.
The Problem: Node.js Dependencies on the Edge
The most essential thing to understand about Cloudflare Pages is that it runs on the Edge Runtime, not a standard Node.js server. This means standard libraries like fs (file system) or crypto simply do not exist.
While working on the migration, my build failed immediately because I was using a few Nodejs sdk based libraries, for instance, the twilio Node.js SDK. Just like we instantiate objects in OOP, I was instantiating the client using twilio(sid, token). However, this SDK dragged in heavy internal Node.js modules that crashed the build.
The solution was not to look for a different library, but to refactor the logic to use standard Web APIs (fetch) and I did this to other similar libraries ' implementations that we have in the codebase.
The 25MB Hard Limit
Even after fixing the runtime errors, I hit a second, harder wall. Cloudflare has a strict infrastructure limit: your entire application (API routes + Server Components) must compress into a single Worker file smaller than 25 MiB.
My deployment log returned this error: Generated Pages Functions bundle size (49616348) is over the limit of 25.0 MiB
It was 49MB, nearly double the limit. At this point, I decided to strip out large packages and move their logic to the edge. Given that we use Supabase for both our web and mobile clients, refactoring Twilio into a single shared Edge Function made perfect architectural sense. It helped, but it wasn’t enough. We discovered that Next.js was still bundling massive ‘polyfills’ code mimicking Node.js, along with heavy UI libraries like recharts and framer-motion into the server bundle.
To solve this, I had to configure two advanced settings.
Configuration: Compatibility Flags and Webpack
First, I enabled the nodejs_compat flag in Cloudflare. This tells the runtime to use its own built-in, lightweight versions of Node tools instead of making Next.js bundle massive shim files.

Second, I had to force Webpack to be aggressive. Next.js 16 defaults to Turbopack, but to get the file size down, I needed to explicitly use Webpack to minimise the code and “tree-shake” (remove) unused exports from my heavy libraries, and also make sure it’s in the build script in the package.json.
Conclusion
Migrating to the Edge requires a shift in how we handle dependencies.
- Runtime Compatibility: You cannot assume Node.js APIs exist. If a library depends on
fsorcrypto, you must replace it or usefetch. - Bundle Size: The 25MB limit is real. You must actively manage your imports.
- The
nodejs_compatflag is essentially a "magic switch" that reduces bundle bloat by using Cloudflare's internal tools. - Next.js 15/16 Params: As a side note, remember that
paramsandsearchParamsare now Promises in the new Next.js versions. You mustawaitthem, or your build will fail during static generation.
Do ask questions for clarifications and make corrections & suggestions, I expect them.
Also published on Medium.
