Skip to content

Search docs

Jump between documentation pages.

Browse docs

Adapters & runtimes

DaloyJS is a REST API backend framework. The core only ever sees Request → Response. Runtime-specific concerns, sockets, signals, edge handlers, Lambda event shapes, live in thin adapters at the edge. Choose the adapter for the place you want to deploy your API.

One app core, many runtimes
web-standard coreYour DaloyJS AppRequest -> Response
runtimeNode.js · Bun@daloyjs/core/node · /bun
runtimeDeno@daloyjs/core/deno
edgeCloudflare Workers / workerd@daloyjs/core/cloudflare
serverlessVercel / Netlify@daloyjs/core/vercel · /netlify
edge / serverlessFastly / AWS Lambda@daloyjs/core/fastly · /lambda
serverlessAzure Functions@daloyjs/core/azure
The core only ever sees a Request and returns a Response. Each thin adapter handles one platform's sockets, signals, or event shape, so the same app ships everywhere without a rewrite.

Pick a target

Runtimes (you own the process)

Edge & serverless (platform owns the process)

Containers on Google Cloud Run, Fly.io, Render, Railway, or Kubernetes use the Node adapter. See Deployment.

What each adapter gives you

Every adapter runs the same routing, validation, security headers, and problem+json errors. What differs is what the platform hands the adapter:

AdapterReal client peerStreaming responsesWebSockets (app.ws)Graceful shutdownOTLP telemetry flush
Node (/node)Yes, from the socketYesYesSIGTERM/SIGINTInterval + on shutdown
Bun (/bun)Yes, from the socketYesYesSIGTERM/SIGINTInterval + on shutdown
Deno (/deno)Yes, from the socketYesNoSIGTERM/SIGINTInterval + on shutdown
Cloudflare Workers, workerd (/cloudflare)No, use behindProxyYesNoPlatform-managedPer request via ctx.waitUntil
Vercel (/vercel)No, use behindProxyYesNoPlatform-managedPer request via waitUntil when present
Netlify v2 / Edge (/netlify)Yes, from context.ipYesNoPlatform-managedPer request via context.waitUntil
Fastly Compute (/fastly)No, use behindProxyYesNoPlatform-managedPer request via event.waitUntil
AWS Lambda (/lambda)Yes, from the eventBuffered, or toLambdaStreamHandlerNoPlatform-managedAwaited before returning
Azure Functions (/azure)No, use behindProxyBuffered, or stream: trueNoPlatform-managedAwaited before returning
  • Real client peer is what getConnInfo(ctx.request) returns. It never comes from a header a client could fake. Where the platform does not expose it, declare behindProxy so rateLimit() and resolveClientIp() read the platform's X-Forwarded-For. See Reverse proxy.
  • Graceful shutdown means the adapter drains your app.onShutdown hooks on a signal. On platform-managed hosts your code is never sent SIGTERM, so do not rely on shutdown hooks there.

The Node adapter runs the whole test suite. Deno, Bun, and workerd also run a smoke suite on the real runtime binaries in CI, against the published dist/ build, on every change.

Roll your own

If your runtime exposes the web-standard Request / Response contract and isn't listed above, you don't need an adapter at all, pass the incoming request straight to app.fetch:

ts
// modules-format (Cloudflare Workers, Deno, Bun, etc.)
export default {
  fetch(request: Request): Promise<Response> {
    return app.fetch(request);
  },
};

See also

  • Deployment: Docker, reverse proxies, health checks, and platform guides (Fly.io, Render, Railway, Heroku, Google Cloud Run).
  • Scaffolder: pnpm create daloy ships runtime-specific templates.
Edit this page on GitHub

Last updated