Skip to main content
Migrating Off the Vercel Edge Runtime: Field Notes

Migrating Off the Vercel Edge Runtime: Field Notes

October 4, 2026
Frontend Engineering
5 min read

Key takeaways

- The Edge Runtime is a deprecated, isolate-based runtime with a restricted API surface — no `fs`, no native Node crypto module, only a partial `Buffer` polyfill.

- Dropping `runtime = 'edge'` does not break streaming. ReadableStream, Server-Sent Events, and AI SDK token streaming all work on the default Node.js runtime with zero extra configuration.

- Fluid Compute reuses warm function instances across concurrent requests instead of spinning up one instance per request — that's the mechanism that replaced "Edge is faster to cold-start" as the main argument for choosing it.

- Next.js Middleware on Vercel now runs on the full Node.js runtime too, so middleware code no longer has to be written against the Edge's restricted environment.

- The part of a migration most likely to break is a dependency with Edge-only assumptions baked in, not the runtime configuration line itself.

Why are we moving client projects off the Edge Runtime?

Because the Edge Runtime no longer buys a project anything the default Node.js runtime doesn't also provide on Vercel. We've gone through client codebases with `runtime = 'edge'` pinned from a time when it was the only way to get low cold-start, globally distributed execution. That argument doesn't hold anymore: Fluid Compute gives the Node.js runtime the same distribution model, while keeping the full Node.js API surface instead of the Edge's restricted V8-isolate subset.

What capabilities does a route lose by staying on the Edge Runtime?

The Edge Runtime does not provide `fs`, does not provide Node's native `crypto` module, and only partially polyfills `Buffer`. Package size is also far more constrained than the 5 GB limit Fluid Compute allows, which matters the moment a dependency pulls in a native binding or a tool like Playwright. On Edge, those dependencies fail at build time or misbehave silently at runtime — we've traced production bugs back to exactly this kind of polyfill gap.

What's the first thing that breaks during a migration off Edge?

It's rarely the handler body itself — it's a feature-detect or an import that assumed Edge. Code that checks the `EdgeRuntime` global to branch behavior, auth or database clients that ship a separate edge-compatible entry point behind a conditional export, and middleware matchers written narrowly around Edge's restrictions are the three places worth checking before touching the runtime configuration. The build usually still succeeds; the breakage shows up at request time instead.

Does streaming still work if the Edge Runtime is removed?

Yes, and this is the misconception that stops teams from migrating. Streaming a response — a ReadableStream, Server-Sent Events over text/event-stream, token-by-token AI output — is not an Edge-exclusive capability. The exact same handler code runs unchanged on the default Node.js runtime; only the `runtime = 'edge'` export needs to go. What changes is that `fs`, native `crypto`, and the rest of the Node.js standard library become available if the route ever needs them.

Edge Runtime vs. Node.js on Fluid Compute: what actually differs?

- Node.js APIs (fs, crypto, net): restricted or polyfilled on Edge, full access on Node.js.

- npm package compatibility: partial on Edge (native bindings often fail), full on Node.js within the package size limit.

- Package size limit: small and isolate-constrained on Edge, up to 5 GB on Fluid Compute.

- Cold starts: fast and isolate-based on Edge, reduced on Fluid Compute via instance reuse across concurrent requests.

- Max execution duration: a short isolate-based limit on Edge, up to 300 seconds by default on Node.js.

- Streaming and Server-Sent Events: supported on both — not an Edge-exclusive feature.

- WebSockets: not supported on Edge, supported on Node.js.

How do we verify an Edge-to-Node migration before shipping it?

We remove the runtime export one route at a time rather than across the whole app at once, which makes any regression trivial to bisect. We run the full test suite, with particular attention to anything that touches the route's dependencies, since Edge-specific fallbacks can mask bugs that only Node's real APIs expose. We hit streaming endpoints manually with `curl -N` to confirm the response still flushes incrementally instead of buffering. Then we check the function's logs for execution duration and invocation count after a day of real traffic, which is what tells us whether Fluid Compute's instance reuse is actually kicking in for that route.

FAQ

**Q:** Do you need the Edge Runtime to stream AI responses in Next.js?

**A:** No. Streaming a ReadableStream or Server-Sent Events response works on the default Node.js runtime; the Edge Runtime is not required for token-by-token AI output.

**Q:** What happens to routes still pinned to `runtime = 'edge'` today?

**A:** They keep running, but Vercel and Next.js are steering new code toward the Node.js runtime on Fluid Compute, so staying on Edge becomes a maintenance cost rather than a performance advantage.

**Q:** Does dropping the Edge Runtime hurt latency for globally distributed users?

**A:** In practice the gap closes, because Fluid Compute reuses warm instances across concurrent requests instead of creating a new isolate per request — that was the main mechanism behind Edge feeling faster.

**Q:** Can Next.js Middleware run on Node.js instead of Edge?

**A:** Yes. Middleware on Vercel supports the full Node.js runtime under Fluid Compute, so it no longer has to be written against the Edge's restricted API surface.

**Q:** What's the biggest risk in an Edge-to-Node migration?

**A:** A dependency with Edge-only assumptions — a library with a separate edge entry point, or code that feature-detects the `EdgeRuntime` global — is more likely to break than the route handler itself.