For years, "full Next.js support" was something only Vercel could credibly claim. Every other platform — Netlify, Cloudflare, AWS, and every self-hosted PaaS behind them — had to guess at how Vercel's build output actually worked, then reimplement Incremental Static Regeneration (ISR), Image Optimization, and Edge Middleware from the outside. Next.js 16.2 just closed that gap at the source: it ships a stable, public Adapter API that turns "how does Vercel build this?" from a reverse-engineering exercise into a typed, documented contract any platform can implement and test against.
That's the concrete thing that changed. Here's what the contract actually contains, what it doesn't fix yet, and what it would take for a self-hosted platform like bex to build a native adapter against it instead of shipping a Dockerfile and hoping for the best.
A year-long RFC, not a surprise
The Adapter API didn't appear overnight. Vercel opened it as an RFC in vercel/next.js discussion #77740 in April 2025, explicitly framed as fixing the reverse-engineering problem below, and spent roughly a year iterating on it in the open with a working group that included engineers from Netlify, Cloudflare, Google Cloud, AWS Amplify, and OpenNext before landing it as stable in 16.2. That matters for how much to trust the contract: it wasn't drafted by Vercel alone and handed down — the platforms it's meant to unblock had a seat at the table shaping what fields AdapterOutputs needed to expose before any of them tried to build against it.
What the Adapter API actually is
An adapter is a module that exports an object implementing the NextAdapter interface, wired in via next.config.js's experimental.adapterPath. It implements two hooks:
modifyConfig— runs when Next.js loads its configuration, before the build starts. It lets the adapter adjust build behavior for its target platform (for example, forcing a particular output mode or runtime).onBuildComplete— runs after compilation and pre-rendering finish, and receives the full build description asAdapterOutputs.
AdapterOutputs is the actual payload: typed arrays covering pages, middleware, appPages, pagesApi, appRoutes, prerenders, and staticFiles, each carrying routes, headers, rewrites, redirects, and a runtime target. For partially prerendered routes specifically, onBuildComplete also exposes outputs.prerenders[].fallback.filePath and .postponedState — the two pieces an adapter needs to seed and resume Partial Prerendering correctly.
None of this is private anymore. Vercel's own production adapter is built against the identical public interface — no hooks reserved for Vercel, no undocumented fields the reference implementation reads that a third party can't. That's the structural change: the contract Vercel's build pipeline targets and the contract available to everyone else are now the same document.
Structurally, an adapter module looks like this:
// adapter.ts
export default {
name: "bex",
async modifyConfig(config) {
// adjust build behavior for bex's target runtime before compilation
return config;
},
async onBuildComplete({ outputs, routes }) {
// outputs.prerenders, outputs.middleware, outputs.appRoutes, etc.
// map each onto bex's own infrastructure here
},
} satisfies NextAdapter;There's no magic beyond that: a platform's entire integration surface is "read the typed output, do something with it" — which is exactly what used to require guesswork.
What every non-Vercel platform used to have to do instead
Before 16.2, a platform that wanted real Next.js support — not just "serves a Node app" but ISR, Image Optimization, and Edge Middleware working correctly — had exactly one path: reverse-engineer Vercel's private build output. That's literally what OpenNext does: it takes a Next.js build, splits it into platform-specific pieces (Lambda functions for SSR and API routes, static assets for S3/CDN, background jobs for ISR revalidation), and re-implements Vercel-only behavior using substitute infrastructure — DynamoDB standing in for Vercel's ISR cache, Sharp standing in for Vercel's Image Optimization service. It works, but every layer of it is inference: "this is probably what Vercel's build output means" rather than "this is documented as what it means."
Self-hosted PaaS platforms that don't have OpenNext's engineering budget settled for less. The common pattern on Coolify, Dokploy, and similar Docker-first platforms today is Next.js's output: "standalone" mode: a self-contained Node server in a container, no special integration beyond that. It runs, but three specific things degrade silently:
- ISR doesn't share state across replicas. Standalone mode's revalidation cache is per-process. Scale a Next.js service to two containers behind a load balancer and each one regenerates and serves stale pages independently — correct on a single instance, silently inconsistent the moment you scale out, unless you wire in an external cache like Redis yourself.
- There's no real Image Optimization service. Vercel's
next/imagecomponent expects an optimization endpoint; standalone mode either falls back to unoptimized images or requires the operator to stand up their own resizing pipeline. - Edge Middleware has no platform equivalent. Middleware that Vercel would run at the edge, close to the request, just runs as regular Node code in the container — functionally similar for a lot of cases, but not the same latency or isolation model, and nothing in a Dockerfile-based deploy tells the platform this code wants edge placement.
None of these are secret; they're accepted trade-offs of "Dockerfile in, container out" hosting. But they exist specifically because the platform never knew what it was actually shipping — a standalone container has no structured description of which routes are prerendered, which need revalidation, which want edge placement. The Adapter API is that structured description.
The bar an adapter actually has to clear
Publishing a typed contract doesn't automatically produce working adapters — Next.js also publishes the correctness bar as a shared test suite, and it's the same one Vercel's own adapter has to pass. Becoming a verified adapter (listed in Next.js's own deploying-to-platforms docs, hosted under the Next.js GitHub org) requires two things: the adapter must be open source, and it must pass the full suite of 9,000-plus end-to-end tests covering streaming behavior, caching interactions, client-side navigation, and edge-case routing. It's a binary contract — pass or fail, not "mostly works." A platform can't claim partial credit for handling static pages correctly while silently mishandling PPR fallback state; the suite either accepts the adapter or it doesn't.
As of the 16.2 release, that bar has been cleared by exactly two adapters: Vercel's own, and a community-built adapter for Bun. Netlify, Cloudflare, and AWS (via OpenNext) are publicly building toward it; Google Cloud's Firebase team has likewise announced their App Hosting adapter as in-progress collaboration, not a shipped, verified artifact. The RFC's headline collaborators — Netlify, Cloudflare, Google Cloud, AWS Amplify, OpenNext — are all named as co-authors of the contract, not platforms that have already cleared it. That distinction matters if you're deciding whether to build one yourself: the field isn't full. As of writing, nobody outside Vercel and one community project has actually finished the race the API made possible.
What a bex-native adapter would concretely do
For a Cluster API-backed platform like bex, the Adapter API turns each of the three degraded behaviors above into a defined integration point instead of a Dockerfile guess:
AdapterOutputs.prerenders— including revalidation windows and PPR fallback state — maps onto a real shared cache keyed per deployment, so ISR revalidation is consistent across every replica in a service instead of per-container and silently stale.- Static and image-bearing routes in
AdapterOutputs— map onto an actual image-resizing service call at request time, replacing the "hope standalone mode's fallback is good enough" default. AdapterOutputs.middleware— with its declared routes and runtime target — maps onto ingress/gateway-level routing rules instead of running as ordinary in-container Node code with no platform awareness that it wanted edge placement.
That's real engineering work — building the adapter, wiring each AdapterOutputs field to actual infrastructure, and then passing the full correctness suite is not a weekend project. The Adapter API doesn't do that work for a platform; what it removes is the uncertainty about what to build against. Before 16.2, a platform had to first reverse-engineer the target before it could even start implementing it. Now the target is a versioned, documented, testable interface — the same one Vercel's own production adapter is held to.
Why this matters even before anyone ships a bex adapter
None of the above requires waiting for a finished adapter to change how a team should evaluate a self-hosted platform's Next.js story today. Two things are now checkable independently of marketing copy:
- Whether a platform's Next.js support is adapter-based or Dockerfile-based is now a yes/no question with a real answer, not a matter of trusting a features page. A platform running standalone-mode containers behind a load balancer inherits the ISR, Image Optimization, and Edge Middleware gaps described above, adapter API or not — publishing an adapter and actually wiring it into the default deploy path are two different milestones.
- Whether a claimed adapter is verified is a fact anyone can check against Next.js's own deploying-to-platforms docs, since the correctness bar is public and binary. A platform announcing "Next.js adapter support" without listing there hasn't cleared the same bar Vercel's own adapter has to clear — worth asking about directly rather than assuming parity.
For bex specifically, the practical roadmap question isn't "can we support Next.js" — a Dockerfile already runs a standalone build today — it's "when does it make sense to move from a container that happens to run Next.js to a native adapter that understands it." That's the difference between a platform that hosts Next.js apps and one that actually integrates with the framework's own caching, image, and middleware model. The Adapter API is what makes that upgrade path concrete instead of aspirational: a defined interface, a public test suite, and — as of 16.2 — exactly one platform's worth of proof that it's achievable outside Vercel itself.
"Full Next.js support" stops being a Vercel-exclusive claim backed by private knowledge, and starts being a claim any platform can make and any developer can verify by pointing the shared test suite at it.
Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. Star the repo on GitHub or deploy your first app today.



