Edge Runtime Simulator
edge-runtime is a JavaScript/TypeScript library, currently at version 4.0.1, developed by Vercel. It provides a robust, spec-compliant environment for simulating Vercel Edge Functions or any Web-standard compliant JavaScript code within Node.js or a CLI. This enables local development, testing, and debugging of Edge Functions without requiring actual deployment, significantly streamlining the development workflow. The library aims to faithfully replicate the Edge Function environment, offering Web APIs like `fetch`, `Request`, `Response`, and `URL` as globals within its isolated context. It maintains an active release cadence, with major versions typically aligning with Node.js LTS updates or substantial API enhancements, as demonstrated by the v4.0.0 release which raised the minimum Node.js version requirement. Its core differentiation lies in providing a high-fidelity simulation of the Vercel Edge context.
Common errors
-
Error: The 'EdgeRuntime' class is not a constructor
cause Attempting to use `require()` for `EdgeRuntime` in an environment where ESM is expected or configured for the package, or incorrect import syntax.fixEnsure you are using `import { EdgeRuntime } from 'edge-runtime';` for ESM contexts. If stuck on CommonJS, you might need to configure your build system or Node.js environment for ESM compatibility or target an older major version of `edge-runtime` if one exists with CJS support. -
ReferenceError: fetch is not defined
cause Trying to use the `fetch` global outside of the `EdgeRuntime` context in a standard Node.js environment, or within evaluated code before the runtime is properly initialized.fixEnsure `fetch` calls are made within the JavaScript code string passed to `runtime.evaluate()`, or use `await runtime.dispatchFetch(request)` to simulate an external fetch event against the runtime. -
Node.js version 16 is not supported by edge-runtime@4.x. Please upgrade to Node.js >=18.
cause Running `edge-runtime` version 4.x or higher on an incompatible Node.js version (specifically 16 or lower).fixUpgrade your Node.js installation to version 18 or later. Alternatively, if Node.js 16 support is critical, you must use `edge-runtime` version `^3.0.0` or earlier.
Warnings
- breaking Version 4.0.0 of `edge-runtime` dropped support for Node.js 16. Using the package with Node.js versions older than 18 will result in errors.
- gotcha The `EdgeRuntime` creates an isolated environment. Node.js built-in modules (e.g., `fs`, `path`) and externally installed Node.js packages are not directly accessible within the code evaluated by `runtime.evaluate()` unless explicitly passed as `initialGlobals` or polyfilled.
- gotcha Web APIs like `fetch`, `Request`, `Response`, `URL`, `console`, etc., are available as globals within the code evaluated by the EdgeRuntime. Attempting to `import` these directly from `edge-runtime` or other libraries will lead to incorrect behavior or `undefined` errors.
Install
-
npm install edge-runtime -
yarn add edge-runtime -
pnpm add edge-runtime
Imports
- EdgeRuntime
const { EdgeRuntime } = require('edge-runtime');import { EdgeRuntime } from 'edge-runtime'; - EdgeRuntimeOptions
import type { EdgeRuntimeOptions } from 'edge-runtime'; - Request
import { Request } from 'edge-runtime';const request = new runtime.Request('https://example.com');
Quickstart
import { EdgeRuntime } from 'edge-runtime';
async function runEdgeFunctionSimulation() {
// Instantiate the Edge Runtime, optionally providing initial globals
const runtime = new EdgeRuntime({
initialGlobals: {
// Simulate environment variables or other global objects
MY_SECRET_KEY: process.env.MY_SECRET_KEY ?? 'default-secret',
SOME_CONFIG: { foo: 'bar' }
}
});
// Define your Edge Function code as a string
const edgeFunctionCode = `
addEventListener('fetch', event => {
const url = new URL(event.request.url);
if (url.pathname === '/api/greet') {
event.respondWith(new Response('Hello from the Edge!', {
status: 200,
headers: { 'content-type': 'text/plain' }
}));
} else if (url.pathname === '/api/config') {
event.respondWith(new Response(JSON.stringify(SOME_CONFIG), {
status: 200,
headers: { 'content-type': 'application/json' }
}));
} else if (url.pathname === '/api/secret') {
event.respondWith(new Response(MY_SECRET_KEY, {
status: 200,
headers: { 'content-type': 'text/plain' }
}));
} else {
event.respondWith(new Response('Not Found', { status: 404 }));
}
});
`;
// Evaluate the Edge Function code within the simulated runtime
runtime.evaluate(edgeFunctionCode);
// Simulate an incoming fetch request
const request1 = new runtime.Request('https://example.com/api/greet');
const response1 = await runtime.dispatchFetch(request1);
console.log('Response 1 Status:', response1.status);
console.log('Response 1 Body:', await response1.text());
const request2 = new runtime.Request('https://example.com/api/config');
const response2 = await runtime.dispatchFetch(request2);
console.log('Response 2 Status:', response2.status);
console.log('Response 2 Body:', await response2.json());
const request3 = new runtime.Request('https://example.com/api/secret');
const response3 = await runtime.dispatchFetch(request3);
console.log('Response 3 Status:', response3.status);
console.log('Response 3 Body:', await response3.text());
}
runEdgeFunctionSimulation().catch(console.error);