Next.js error
A Node.js API Is Not Supported in the Edge Runtime
The error
A Node.js API is used (process.cwd at line: 14) which is not supported in the Edge Runtime.Something in the import graph of an edge-running file reaches a Node built-in. The message names the API and the line, and the fix is usually to move the code rather than to polyfill it.
A Node.js API is used (process.cwd at line: 14) which is not supported in the
Edge Runtime.
The edge runtime is a web-standard environment: fetch, Request, Response, URL, Web Crypto. It has no filesystem, no process beyond a small shim, no net, and none of the Node built-ins that assume an operating system underneath.
The message names the API and the line, which is more help than it first looks.
It is usually the proxy, and usually an import
proxy.ts compiles for the edge runtime by default, and so does everything in its import graph. That graph is larger than people expect:
// proxy.ts
import { logger } from '@/lib/logger' // reads a path with `fs` at module scopeThe proxy itself touched nothing. The logger did, at import time, and import time is enough.
Trace it from the named file upward rather than reading the proxy. next build reports the file and line; the question is which import chain reaches it.
Three fixes, in the order worth trying
Move the import out of the edge path. If one branch of a function needs a heavy module, import it inside that branch rather than at module scope, or split the module so the edge file imports only the part that is web-standard. This is the cheapest fix and it is correct more often than it sounds, because most of these imports exist for a path the proxy never takes.
Swap to a web-standard equivalent. A good deal of Node-only code has a direct replacement: crypto.createHash becomes crypto.subtle.digest, Buffer becomes TextEncoder and Uint8Array, a path join becomes string handling on a URL. The result works on both runtimes, which is a better position than having two code paths.
Move the work. If the code needs a filesystem or a TCP socket, it needs Node, and no amount of shimming changes that. Put it in a Route Handler with export const runtime = 'nodejs' and have the proxy decide whether to call it. The proxy should be doing very little anyway - it runs on every matched request, and what it costs is worth measuring.
The polyfill temptation
Aliasing a Node built-in to a shim makes the build pass. Whether it makes the code work depends entirely on which built-in.
crypto shims to Web Crypto reasonably. fs does not shim to anything, because there is no filesystem to shim to - what you get is a module that resolves and then fails at the first call, which is the same bug moved to runtime where it is harder to see.
Build errors that only appear on one runtime are a routine finding in a technical audit, and the usual root cause is the same: a module that was fine everywhere until something edge-bound imported it.
