Edge Compatibility
Volten is a hybrid runtime framework with a Node.js server entry point and a Web Fetch entry point. app.createFetch() is designed for runtimes that provide the Web Fetch APIs (Request, Response, Headers, and ReadableStream). Compatibility depends on the platform's API support and restrictions; verify the target platform before deploying.
Universal Runtime Vision
Share routes and business logic where they rely on Volten's portable APIs. Platform-specific capabilities and deployment conventions still differ. Supported entry points include:
- Node.js (via native
http/httpssockets) - Cloudflare Workers (via
app.createFetch()) - Vercel Edge Functions (via Edge runtime)
- Bun & Deno (via standard Web Fetch APIs)
import { App } from "volten";
const app = new App();
app.get("/api/greeting", (ctx) => {
ctx.json({
message: "Hello from Volten!",
runtime: ctx.runtime, // 'node' | 'edge'
});
});
// For Cloudflare Workers or Edge environments:
export default {
fetch: app.createFetch(),
};Edge Runtime Detection (isEdge.ts)
Volten provides intelligent, zero-config environment sniffing in src/utils/isEdge.ts. The isEdge() utility executes a multi-factor detection strategy to determine if the active runtime lacks Node.js APIs or restricts dynamic code generation.
Detection Heuristics
isEdge() evaluates the following conditions in priority order:
- Manual Override: If
setIsEdge(boolean)was explicitly set (e.g. in tests), that value is returned immediately. - Vercel Edge Runtime: Checks if
globalThis.EdgeRuntimeis a string. - Cloudflare Workers Navigator: Checks if
navigator.userAgentcontains"Cloudflare-Workers". - Cloudflare Workers Globals: Checks for the existence of
globalThis.WebSocketPair. - Environment Variables: Checks whether any of the following environment variables indicate an edge container:
process.env.NEXT_RUNTIME === 'edge'process.env.EDGE_RUNTIME === 'true'or'1'process.env.VOLTEN_RUNTIME === 'edge'process.env.NODE_ENV === 'edge'
- Missing Process Global: Detects environments where Node's
processglobal is undefined (typeof process === 'undefined'). - Eval Restriction Probe (
checkEvalBlocked): Probes whether dynamic function construction is blocked:typescriptIftry { new Function(""); evalBlocked = false; } catch { evalBlocked = true; }new Function("")throws an error due to platform security policies or Content Security Policy (CSP),isEdge()returnstrue.
Dynamic Compilation & Fallbacks
Many Edge environments (like Cloudflare Workers and strict serverless containers) disable arbitrary code evaluation (eval and new Function(...)) for security reasons. Volten adapts dynamically based on isEdge():
1. Middleware Pipeline (compileMiddlewareChain)
- Node.js: Volten may use dynamic function construction (
new Function(...)) to compile a composed middleware chain. This is an implementation detail and does not eliminate all allocations. - Edge Runtime: When
isEdge()returnstrue, Volten usescreateDynamicMiddlewareChain()instead ofnew Function(...). The chain is designed to preserve Volten's middleware semantics; test middleware that depends on runtime-specific APIs in each target environment.
// src/core/compose.ts
export function compileMiddlewareChain(chain: VoltenHandler[]): VoltenChainHandler {
if (isEdge()) {
return createDynamicMiddlewareChain(chain);
}
// JIT compilation with new Function(...)
}2. JSON Serialization (voltJson & compileVoltJson)
- Node.js: Volten can use shape-specific compiled serializers for eligible payloads.
- Edge Runtime: Serialization behavior depends on the runtime and serializer path; use native
JSON.stringify()as the general compatibility baseline and benchmark before assuming a speedup.
The EdgeRequestContext
When handling requests via app.createFetch(), Volten utilizes EdgeRequestContext instead of NodeRequestContext:
- Web Request: Accessible via
ctx.reqorctx.rawReqas a nativeRequest. - Standard Response: Produces a native Web
Responseobject accessible viactx._edgeResponsePromise. - Return Value Ergonomics: In addition to
ctx.send()andctx.json(), handlers in Edge mode can directly return values:typescript// Return an object (auto-serialized to JSON) app.get("/user", () => ({ id: 1, name: "Alice" })); // Return a string (text/plain) app.get("/status", () => "OK"); // Return a raw Web standard Response app.get("/custom", () => new Response("custom", { status: 201 }));
Deployment Examples
Cloudflare Workers
import { App } from "volten";
const app = new App();
app.get("/", (ctx) => {
ctx.send("Hello from Cloudflare Workers!");
});
app.get("/env", (ctx) => {
// Edge runtime bindings passed in env
const apiKey = (ctx.env as Record<string, string>)?.["API_KEY"];
ctx.json({ hasKey: Boolean(apiKey) });
});
export default {
fetch: app.createFetch(),
};Vercel Edge Middleware / Functions
import { App } from "volten";
export const config = {
runtime: "edge",
};
const app = new App();
app.get("/api/edge", (ctx) => {
ctx.json({ platform: "Vercel Edge" });
});
export default app.createFetch();Bun Native HTTP Server
import { App } from "volten";
const app = new App();
app.get("/", (ctx) => {
ctx.send("Running fast on Bun!");
});
export default {
port: 3000,
fetch: app.createFetch(),
};Testing & Overrides (setIsEdge)
For testing environments or specialized runtime wrappers, you can manually force or reset the edge detection state:
import { isEdge, setIsEdge } from "volten"; // or from 'volten/utils'
// Force Edge mode
setIsEdge(true);
console.log(isEdge()); // true
// Force Node.js mode
setIsEdge(false);
console.log(isEdge()); // false
// Revert to automatic runtime detection
setIsEdge(null);