Wraps Vercel Edge Runtime testing patterns: the @edge-runtime/jest-environment + edge-runtime CLI for executing Web-Standard APIs (Request / Response / fetch) in jest tests, the `vercel dev` local emulator for full route testing, and the Edge vs Node Function divergence (no fs, no Buffer; Request / Response only). Covers the 30s Edge function timeout per vercel.com/docs. Use when testing Vercel Edge Functions or middleware.
80
100%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Vercel Edge Runtime is V8-isolate-based (sub-30ms cold starts
per cold-start-budget-reference)
with a constrained API surface: no filesystem access, so no Node
fs or child_process ("you can't read or write to the
filesystem"). Buffer is an exception, being "globally exposed to
maximize compatibility with existing Node.js modules". Per
vercel.com/docs/functions/edge-runtime,
"The Edge runtime provides a subset of Web APIs such as fetch, Request, and Response."
Tests need the same constraints. Vercel ships
@edge-runtime/jest-environment (and standalone edge-runtime
CLI) for this.
vercel dev integration.npm install --save-dev @edge-runtime/jest-environment edge-runtime{
"jest": {
"testEnvironment": "@edge-runtime/jest-environment"
}
}This swaps Jest's default jsdom / node env for an Edge-
constrained one. Tests that try to import fs or use Buffer
fail - same as production.
// pages/api/hello.ts (Vercel Edge Function)
export const config = { runtime: 'edge' };
export default async function handler(req: Request): Promise<Response> {
return new Response(JSON.stringify({ ok: true }), {
headers: { 'Content-Type': 'application/json' },
});
}import handler from './hello';
test('returns ok', async () => {
const req = new Request('https://example.com/api/hello');
const res = await handler(req);
expect(res.status).toBe(200);
expect(await res.json()).toEqual({ ok: true });
});// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
if (request.nextUrl.pathname.startsWith('/admin')) {
if (!request.cookies.get('session')) {
return NextResponse.redirect(new URL('/login', request.url));
}
}
return NextResponse.next();
}import { middleware } from './middleware';
test('redirects unauthenticated /admin', () => {
const request = new Request('https://example.com/admin/dashboard');
const response = middleware(request as any);
expect(response.status).toBe(307); // redirect
expect(response.headers.get('location')).toContain('/login');
});
test('allows authenticated', () => {
const request = new Request('https://example.com/admin', {
headers: { cookie: 'session=valid' },
});
const response = middleware(request as any);
expect(response.headers.get('x-middleware-next')).toBe('1'); // NextResponse.next sentinel
});npm install -g vercel
vercel dev --listen 3000Routes are served exactly as on prod. Now run e2e tests against
http://localhost:3000.
npx edge-runtime ./pages/api/hello.ts
# Spins up a local server in the Edge Runtime environmentnpx jestjobs:
vercel-edge-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v4
- run: npm ci
- run: npx jest| Anti-pattern | Why it fails | Fix |
|---|---|---|
Use jsdom test env for Edge code | Tests pass; Buffer.from(...) works in test but not prod | Use @edge-runtime/jest-environment |
Importing fs / Buffer in handler | Tests fail (good); but production fails too | Use Web Platform APIs (Uint8Array, TextEncoder) |
| Hardcoded path in test | OS-specific | Use Request URL |
| Skipping middleware tests | Auth bypass slips through | Always test middleware separately |
| No 30s timeout test | Edge functions have 30s wall-clock max per lambda-timeout-budget-reference | Test with artificial slowness; assert proper response |
Mocking Request / Response | Loses standard-compliance | Use real Request / Response (Edge env provides them) |
Skip vercel dev for route-tests | Misses routing layer | Run e2e against vercel dev |
cold-start-budget-reference.cold-start-budget-reference,
lambda-timeout-budget-reference.cloudflare-workers-miniflare.