Reference

Adapters

Deployment adapters live under @reckona/mreact-router/adapters/*. They turn the built .mreact output into a runtime-specific request handler or static export.

When to use this page

Use this page when connecting build output to an HTTP server, Cloudflare Worker, AWS Lambda entrypoint, generic edge runtime, or static hosting export.

Adapter imports

import { createNodeRequestHandler } from "@reckona/mreact-router/adapters/node";
import { createCloudflareRequestHandler } from "@reckona/mreact-router/adapters/cloudflare";
import { createAwsLambdaRequestHandler } from "@reckona/mreact-router/adapters/aws-lambda";
import { createEdgeRequestHandler } from "@reckona/mreact-router/adapters/edge";
import { exportStaticApp } from "@reckona/mreact-router/adapters/static";

Runtime map

  • Node servers and containers use createNodeRequestHandler().
  • Cloudflare Workers and Pages advanced mode use createCloudflareRequestHandler() or generated Pages packaging output.
  • AWS Lambda HTTP API, Function URLs, and streaming variants use the AWS Lambda adapter.
  • Generic Fetch-compatible runtimes can use the edge adapter.
  • Static hosting uses exportStaticApp() after building a prerenderable app.

Minimal Node server

import { createServer } from "node:http";
import { createNodeRequestHandler } from "@reckona/mreact-router/adapters/node";

const handler = await createNodeRequestHandler({ outDir: ".mreact" });

createServer(handler).listen(Number(process.env.PORT ?? 3000));

When a trusted reverse proxy terminates TLS, pass trustForwardedProto: true to createNodeRequestHandler() only if the proxy overwrites X-Forwarded-Proto and the Node listener is not directly reachable. This is independent of hostPolicy; the default remains false.

Managed HTTP upgrades

Use startServer() or startDevServer() when an application needs WebSocket or another HTTP upgrade protocol on the same Node server. Browser WebSocket handshakes are not protected by CORS or the browser same-origin policy, and matching cookies are sent with the handshake. Mreact therefore validates the exact serialized Origin before invoking the application handler by default. Validate origin before reading a session or other credentials, then explicitly accept or decline every upgrade.

import { startServer, validateHttpUpgradeOrigin } from "@reckona/mreact-router";
import { WebSocketServer } from "ws";

const allowedOrigins = ["https://app.example.com"];
const wss = new WebSocketServer({ noServer: true });

await startServer({
  outDir: ".mreact",
  port: 3000,
  upgradeOriginPolicy: { allowedOrigins },
  onUpgrade(request, socket, head, context) {
    const origin = validateHttpUpgradeOrigin(request, { allowedOrigins });
    if (!origin.ok || request.url !== "/ws") {
      return context.decline();
    }

    context.accept();
    // Authenticate only after Origin validation.
    wss.handleUpgrade(request, socket, head, (websocket) => {
      wss.emit("connection", websocket, request);
    });
  },
});

Call context.accept() synchronously before delayed verification and call context.decline() for requests the application does not own. A handler that throws, rejects, or leaves an asynchronous decision unresolved closes the socket. close() lets accepted upgrades finish until upgradeCloseTimeoutMs, then destroys only the remaining upgrade sockets while ordinary HTTP responses retain their normal drain behavior. Non-browser clients without an Origin header require an explicit { allowedOrigins, allowMissingOrigin: true } policy and another authentication boundary; use "unchecked" only as an intentional compatibility escape hatch.

Static export

import { exportStaticApp } from "@reckona/mreact-router/adapters/static";

await exportStaticApp({
  outDir: ".mreact",
  exportDir: "dist",
});

API reference: Node adapter, Cloudflare adapter, AWS Lambda adapter, Edge adapter, and Static adapter.