Wise Hustlers — Digital Product & App Development Studio Logo
Get Consultation
By Wise Hustler Admin9/13/20269 min read

Next.js on the Edge: What Edge Runtime Actually Buys You (and What It Costs You)

Next.js on the Edge: What Edge Runtime Actually Buys You (and What It Costs You)

# Next.js on the Edge: What Edge Runtime Actually Buys You (and What It Costs You)

TL;DR: Edge Runtime gives you a smaller, faster-starting JavaScript environment distributed closer to users, in exchange for losing most of the Node.js API surface — no fs, no native modules, and a crypto module that isn't really there. That trade got expensive enough that as of Next.js 16.3, export const runtime = 'edge' is deprecated outright, and Next.js 16's proxy.ts (the replacement for middleware.ts) runs on Node.js only.

Two different runtimes, one framework

Next.js has shipped two distinct JavaScript runtimes for a while now:

  • Node.js runtime — the full Node.js environment: fs, native addons, Buffer, long-running connections, the entire npm ecosystem.
  • Edge Runtime — a V8-isolate-based environment built on Web APIs (fetch, Request, Response, URL, Web Crypto), designed to start in milliseconds and run in many geographic locations at once. It's the same idea behind Cloudflare Workers and Deno Deploy: strip the runtime down to what a JS engine needs, drop the OS-level Node bindings, and you get fast cold starts and small memory footprints.

Historically you opted into Edge per-route with a segment config, and Middleware ran on it by default:

// app/api/hello/route.ts (pre-16.3 pattern)
export const runtime = 'edge'

export async function GET() {
  return new Response(JSON.stringify({ ok: true }), {
    headers: { 'content-type': 'application/json' },
  })
}

That runtime = 'edge' line is the whole pitch and the whole problem, and 2026 is the year that trade-off tipped decisively toward Node.

What Edge Runtime actually buys you

  • Cold start latency. No Node process to spin up — an isolate boots in low single-digit milliseconds, which matters for Middleware that runs on every matched request (auth checks, A/B routing, geolocation redirects).
  • Geographic distribution. Edge Runtime code can execute in points of presence close to the requester rather than a single region, cutting round-trip time for latency-sensitive logic.
  • A forced-small footprint. Because native APIs aren't available, Edge functions tend to stay lean — there's no way to accidentally pull in a 40MB native dependency graph.

This is genuinely useful for what Middleware is supposed to do: fast, stateless request inspection and rewriting before a request hits your real backend logic.

What it costs you: the missing Node.js surface

Edge Runtime is explicitly not Node.js. Per the official Next.js Edge Runtime reference, it exposes a subset of Web-standard APIs and explicitly does not support native Node.js APIs — you can't touch the filesystem, require() is disallowed, and packages must ship as ES Modules with no native Node dependencies to work at all (see Next.js's "Node.js Modules in Edge Runtime" error page, which exists specifically because people hit this constantly).

CapabilityNode.js runtimeEdge Runtime
fs (filesystem)
Native Node addons / most native npm deps
crypto (Node's node:crypto)❌ (use Web Crypto's crypto.subtle / crypto.randomUUID())
BufferNot supported
TCP/raw sockets (pg, direct DB drivers)
fetch, Request, Response, URL
eval / dynamic code execution❌ (blocked for security reasons in Middleware)
Long-running / streaming workLimited — Vercel's Edge Functions must start responding within 25s and can stream up to 300s total (Vercel changelog)

That crypto row is the one that quietly breaks things, because so much of the ecosystem — ORMs, auth libraries, session encryption — assumes Node's crypto is just there.

Where this actually broke something: Prisma in Middleware

This isn't hypothetical. In 2024, developers using Prisma's @prisma/adapter-pg driver adapter (which wraps the pg / node-postgres client) inside Next.js Middleware hit a hard failure: Error: The edge runtime does not support Node.js 'crypto' module. It's tracked as prisma/prisma#24386 and a related follow-up, #24430 — confirmed and reproduced, not user error.

The root cause is that pg itself depends on Node's crypto module internally (for connection auth handshakes), and driver adapters were sold as an edge-compatibility layer for Prisma, but they only move Prisma's query logic to something edge-shaped — they don't fix the underlying database driver's Node dependency. The practical effect: a team that put "check the user's session against the DB" logic in Middleware for a fast-path auth gate found their build compiling fine and their Middleware throwing at request time, because static analysis doesn't always catch a transitive crypto import three dependencies deep.

The same failure mode shows up with next-authnextauthjs/next-auth#10540 documents the identical error when getServerSession-adjacent code path ends up running under the Edge Runtime in Middleware. Auth.js's own Edge Compatibility guide exists as a direct response to this class of bug: split your auth config so the parts that need real database drivers or Node's crypto run in the Node.js runtime, and keep only stateless JWT-decode logic in the Edge-executed path.

The fix pattern in both cases is the same: don't do database access or Node-crypto-dependent work in Edge-executed code. Either move that logic into a Node.js runtime route the Middleware calls out to, or — as of Next.js 16 — just run that logic in the Node.js runtime directly, since that option no longer costs you the "runs everywhere at low latency" benefit for every piece of logic, only the parts that actually need it.

The 2026 shift: Next.js and Vercel are walking Edge back

This is the part that makes "what Edge Runtime costs you" a live question rather than a stable trade-off to memorize once:

1. Middleware became `proxy.ts` in Next.js 16, and the replacement runs on the Node.js runtime only — Edge Runtime is not supported in proxy.ts at all. The old middleware.ts file still works but is deprecated (Next.js's migration doc).

2. As of Next.js 16.3, `export const runtime = 'edge'` is deprecated for route segments (page, layout, route files). Next.js now warns that the Edge Runtime is deprecated and that Node.js — already the default — should be used instead (Next.js's deprecation notice).

3. Vercel has deprecated standalone Edge Functions as a distinct product, recommending Vercel Functions on the Node.js runtime paired with Fluid Compute, which Vercel says runs in the same regions at the same price while removing the Web API restrictions (Vercel's Edge Runtime docs).

The rationale converges on one point: fast concurrency scaling (Fluid Compute) closed most of the cold-start and cost gap that used to justify Edge Runtime's API restrictions, so paying for those restrictions with a crippled Node surface stopped making sense for most application code.

Edge vs Node: what to actually pick today

// proxy.ts — Next.js 16, Node.js runtime only, no config needed
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export default function proxy(request: NextRequest) {
  const country = request.headers.get('x-vercel-ip-country')
  if (country === 'GB') {
    return NextResponse.rewrite(new URL('/uk', request.url))
  }
  return NextResponse.next()
}
  • Building on Next.js 16+? Use proxy.ts and stop thinking about runtime selection for request-boundary logic — it's Node.js now, full API surface included.
  • Still on Next.js 14/15 with `middleware.ts`? Keep Edge-executed code to header/cookie inspection, redirects, and rewrites. Push anything touching a database driver, crypto, or a native dependency into a Node.js API route the middleware calls.
  • Route handlers and pages should just stay on the Node.js runtime (the default) unless you have a specific, measured latency requirement Edge solves and you've confirmed every dependency in that code path is Edge-safe.

If you're already re-architecting request routing or evaluating regional deployment strategy as part of this, that's usually a broader infrastructure conversation than a single runtime flag — the kind of thing that shows up in a cloud and DevOps engagement rather than a one-line config change.

FAQ

Is Edge Runtime being removed from Next.js entirely?

Not immediately — middleware.ts still works and Vercel's Edge Runtime still exists for specific use cases where startup latency genuinely outweighs API access. But the direction is clear: Next.js 16.3 deprecates runtime = 'edge' for routes, and proxy.ts doesn't support Edge at all.

Why did my code work locally but fail with a `crypto` module error in production Middleware?

A dependency several levels deep — commonly a database driver like pg, used directly or via an ORM adapter — imports Node's crypto module. Bundlers sometimes tree-shake around it in dev but the Edge Runtime rejects it at request time. Check whether the failing code path touches a database client or any auth library's server-side session decoding.

Should I still use Edge Runtime for API routes in 2026?

Generally no, unless you have a specific, latency-sensitive use case (geolocation-based redirects, header rewriting, feature-flag routing) and no dependency in that code path needs Node APIs. Fluid Compute on the Node.js runtime has closed most of the performance gap that used to justify Edge.

What's the difference between `middleware.ts` and `proxy.ts` in Next.js 16?

They serve the same network-boundary purpose (running before a request reaches your route), but proxy.ts is the Next.js 16 replacement that runs exclusively on the Node.js runtime — full API access, no Edge Runtime option. middleware.ts still works for now but is deprecated in favor of proxy.ts.

Sources