Next.js 16 vs Remix
Vercel Next.js 16 versus Shopify Remix: server components, data loading, deployment, performance, and the modern React full-stack framework choice.
The source of Next.js — ship the newest features with zero configuration
A global V8-isolate network — zero egress, now with its own Next.js layer, vinext
It depends on your situation. If you want the newest Next.js features with zero lag, choose Vercel — there's no parity risk. If you're running a bandwidth-heavy, global project and prioritize predictable cost, Cloudflare is the right bet; alongside the mature OpenNext, there's now the beta but fast-moving vinext. For critical work, start with OpenNext; try vinext on a new project.
| Category | Vercel | Cloudflare (Workers + Pages) |
|---|---|---|
| Performance | 8/10 | 9/10 |
| Ease of Learning | 9/10 | 6/10 |
| Ecosystem | 9/10 | 7/10 |
| Community | 9/10 | 8/10 |
| Job Market | 8/10 | 7/10 |
| Future-Proof | 8/10 | 8/10 |
// Vercel — Next.js 16 App Router, Cache Components (PPR default) + on-demand purge
// next.config.ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
cacheComponents: true,
};
export default nextConfig;
// app/blog/[slug]/page.tsx — cached data with 'use cache' + cacheTag
import { cacheTag } from "next/cache";
async function getPost(slug: string) {
"use cache";
cacheTag(`post-${slug}`);
const res = await fetch(`https://api.example.com/posts/${slug}`);
return res.json();
}
export default async function BlogPost({
params,
}: {
params: Promise<{ slug: string }>;
}) {
const { slug } = await params;
const post = await getPost(slug);
return (
<article>
<h1>{post.title}</h1>
<div dangerouslySetInnerHTML={{ __html: post.html }} />
</article>
);
}
// app/api/revalidate/route.ts — on-demand purge (Vercel Data Cache)
// "max" = stale-while-revalidate; use { expire: 0 } to drop instantly on webhook
import { revalidateTag } from "next/cache";
import { NextRequest, NextResponse } from "next/server";
export async function POST(req: NextRequest) {
const { slug } = await req.json();
revalidateTag(`post-${slug}`, "max");
return NextResponse.json({ revalidated: true });
}
// vercel.json — region preference and function duration
{
"regions": ["fra1"],
"functions": {
"app/api/revalidate/route.ts": { "maxDuration": 10 }
}
}
// Deploy
// $ vercel --prod// Cloudflare — deploy Next.js 16 to Workers (vinext, official default path)
// 1) Measure compatibility first, then add to the project (Vite config is generated by vinext init)
// $ npx vinext check
// $ npx vinext init
// vite.config.ts — Workers Cache for route-level ISR, KV for data cache
import { cloudflare } from "@cloudflare/vite-plugin";
import { cdnAdapter } from "@vinext/cloudflare/cache/cdn-adapter";
import { kvDataAdapter } from "@vinext/cloudflare/cache/kv-data-adapter";
import { defineConfig } from "vite";
import vinext from "vinext";
export default defineConfig({
plugins: [
vinext({
// cdnAdapter only works when wrangler.jsonc has "cache": { "enabled": true }
cache: { cdn: cdnAdapter(), data: kvDataAdapter() },
}),
cloudflare({
viteEnvironment: { name: "rsc", childEnvironments: ["ssr"] },
}),
],
});
// Deploy — it generates the Worker configuration itself
// $ npx @vinext/cloudflare deploy
// Alternative: OpenNext adapter — open-next.config.ts
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
import r2IncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/r2-incremental-cache";
export default defineCloudflareConfig({ incrementalCache: r2IncrementalCache });
// $ opennextjs-cloudflare build && opennextjs-cloudflare deploy
// Access for Workers — attach the Worker to an Access application
// POST /accounts/{account_id}/access/apps
// "destinations": [{ "type": "worker", "worker_id": "<worker-id>" }]It depends on your situation. If you want the newest Next.js features with zero lag, choose Vercel — there's no parity risk. If you're running a bandwidth-heavy, global project and prioritize predictable cost, Cloudflare is the right bet; alongside the mature OpenNext, there's now the beta but fast-moving vinext. For critical work, start with OpenNext; try vinext on a new project.
Get Free ConsultationNot fully, but close: Cloudflare's new vinext layer supports ~94% of the Next.js 16 API surface (App Router, Server Actions, ISR, middleware) and is the official default path — but it's still beta; the docs say to run `npx vinext check` before adopting it in an existing production app. The more mature `@opennextjs/cloudflare` adapter has a staleness issue (an open GitHub issue) in its R2 cache backend for ISR+Partial Prerendering.