NextRush

@nextrush/adapter-edge

Universal edge runtime adapter for Cloudflare Workers, Vercel Edge, and Netlify Edge.

Connect your NextRush application to edge computing platforms.

Edge runtimes execute code at the network edge, close to users. This adapter provides a universal interface that works across Cloudflare Workers, Vercel Edge Functions, Netlify Edge Functions, and any platform supporting the Web Fetch API.

Edge Runtime Constraints

Edge runtimes lack access to the file system, native modules, and child_process. Review the limitations table before deploying.


Installation

$ pnpm add @nextrush/adapter-edge

Quick Start

The edge adapter creates a standard fetch handler:

import { createApp } from '@nextrush/core';
import { createFetchHandler } from '@nextrush/adapter-edge';

const app = createApp();

app.use(async (ctx) => {
  ctx.json({ message: 'Hello from the Edge!' });
});

export default createFetchHandler(app);

Platform-Specific Handlers

Each edge platform has a dedicated handler factory. Choose the one matching your deployment target.

import { createApp } from '@nextrush/core';
import { createCloudflareHandler } from '@nextrush/adapter-edge';

const app = createApp();

app.use(async (ctx) => {
  ctx.json({
    message: 'Hello from Cloudflare Workers!',
    colo: ctx.raw.req.cf?.colo,
  });
});

export default createCloudflareHandler(app);

Deploy with Wrangler:

wrangler deploy
// api/hello.ts
import { createApp } from '@nextrush/core';
import { createVercelHandler } from '@nextrush/adapter-edge';

const app = createApp();

app.use(async (ctx) => {
  ctx.json({
    message: 'Hello from Vercel Edge!',
    region: process.env.VERCEL_REGION,
  });
});

export const config = { runtime: 'edge' };
export default createVercelHandler(app);
// netlify/edge-functions/api.ts
import { createApp } from '@nextrush/core';
import { createNetlifyHandler } from '@nextrush/adapter-edge';

const app = createApp();

app.use(async (ctx) => {
  ctx.json({ message: 'Hello from Netlify Edge!' });
});

export default createNetlifyHandler(app);

Configure in netlify.toml:

[[edge_functions]]
path = "/api/*"
function = "api"

API Reference

createFetchHandler(app, options?)

Create a universal fetch handler for any edge platform.

import { createFetchHandler } from '@nextrush/adapter-edge';

const handler = createFetchHandler(app, {
  onError: (error, ctx) => {
    console.error('Edge error:', error);
    return new Response('Error', { status: 500 });
  },
});

FetchHandlerOptions

PropertyTypeDescription
onError?(error: Error, ctx: EdgeContext) => Response | Promise<Response>Custom error handler for uncaught exceptions
timeout?numberRequest timeout in milliseconds. Returns 504 Gateway Timeout if exceeded. Recommended: 30000 for Cloudflare, 25000 for Vercel.

createCloudflareHandler(app, options?)

Create a Cloudflare Workers module export.

import { createCloudflareHandler } from '@nextrush/adapter-edge';

// Returns { fetch: FetchHandler }
export default createCloudflareHandler(app);

createVercelHandler(app, options?)

Create a Vercel Edge Function handler.

import { createVercelHandler } from '@nextrush/adapter-edge';

export const config = { runtime: 'edge' };
export default createVercelHandler(app);

createNetlifyHandler(app, options?)

Create a Netlify Edge Function handler.

import { createNetlifyHandler } from '@nextrush/adapter-edge';

export default createNetlifyHandler(app);

createHandler(app, options?)

Alias for createFetchHandler. Use for generic edge deployments.

import { createHandler } from '@nextrush/adapter-edge';

export default { fetch: createHandler(app) };

Error Handling

Customize error responses for edge environments:

const handler = createFetchHandler(app, {
  onError: (error, ctx) => {
    // Log to edge logging service
    console.error('Request failed:', {
      path: ctx.path,
      error: error.message,
    });

    // Return custom error response
    return new Response(
      JSON.stringify({
        error: 'Service temporarily unavailable',
        requestId: ctx.state.requestId,
      }),
      {
        status: 503,
        headers: { 'Content-Type': 'application/json' },
      }
    );
  },
});

Edge Context

EdgeContext exposes a waitUntil() method for fire-and-forget operations that complete after the response is sent:

app.use(async (ctx) => {
  // Fire-and-forget async operations (logging, analytics)
  ctx.waitUntil(
    fetch('https://analytics.example.com/track', {
      method: 'POST',
      body: JSON.stringify({ path: ctx.path }),
    })
  );

  ctx.json({ ok: true });
});

Cloudflare Bindings

Cloudflare bindings (KV, D1, R2, secrets) are passed as the second argument to the Workers module fetch handler. createCloudflareHandler receives (request, env, ctx) internally but does not expose env on the NextRush context.

To access bindings, wrap your app setup in a closure:

import { createApp } from '@nextrush/core';
import { createFetchHandler } from '@nextrush/adapter-edge';
import type { FetchHandler } from '@nextrush/adapter-edge';

interface Env {
  MY_KV: KVNamespace;
  MY_DB: D1Database;
}

export default {
  async fetch(request: Request, env: Env, execCtx: ExecutionContext): Promise<Response> {
    const app = createApp();

    app.use(async (ctx) => {
      const value = await env.MY_KV.get('key');
      ctx.json({ value });
    });

    const handler = createFetchHandler(app);
    return handler(request, execCtx);
  },
};

For production use, create the app and handler at module scope and pass env through middleware state to avoid per-request overhead.


Edge Limitations

Edge runtimes have constraints compared to Node.js:

FeatureEdge Support
fs module❌ Not available
child_process❌ Not available
Native modules❌ Not available
WebSocket⚠️ Platform-specific
Long-running tasks⚠️ Time limits apply
Request body✅ Streaming supported
Fetch API✅ Full support

Design your application with these constraints in mind.


Cold Start Optimization

Minimize cold start times:

// ✅ Good: Create app at module level
const app = createApp();
app.use(/* middleware */);

const handler = createFetchHandler(app);
export default { fetch: handler };

// ❌ Avoid: Creating app per request
export default {
  fetch: (req) => {
    const app = createApp(); // Cold start overhead
    return createFetchHandler(app)(req);
  },
};

TypeScript

All exports are fully typed:

import type { Application } from '@nextrush/core';
import type {
  FetchHandler,
  FetchHandlerOptions,
  EdgeExecutionContext,
} from '@nextrush/adapter-edge';
import {
  createFetchHandler,
  createCloudflareHandler,
  createVercelHandler,
  createNetlifyHandler,
  detectEdgeRuntime,
} from '@nextrush/adapter-edge';

const options: FetchHandlerOptions = {
  timeout: 25_000,
  onError: (error, ctx) => new Response('Error', { status: 500 }),
};

const handler: FetchHandler = createFetchHandler(app, options);

On this page