Where to use DaloyJS
DaloyJS is a contract-first TypeScript web framework. It takes an HTTP Request and returns a Response, with validation, OpenAPI, security, and a typed client all wired in. That description fits a lot of jobs, and a few it doesn't. This page is the beginner's map.
If you only read one thing: DaloyJS is excellent at the "your code answers an HTTP request" role , API server, microservice, BFF, webhook receiver, WebSocket server, MCP server. It is nota router that proxies traffic to other services, a load balancer, or a page-rendering UI framework. For those, pair it with something purpose-built and let DaloyJS be the smart endpoint behind them.
The quick verdict
For each role, here is the short answer.
| Role | Fit | In one sentence |
|---|---|---|
| API server | Excellent | This is the home position. |
| Web server (HTML, static files) | Works, but not the point | It can return HTML, but a CDN or Next.js is better at it. |
| Microservice (one of many) | Excellent | Use the internal-service preset behind a mesh. |
| Backend-for-Frontend (BFF) | Excellent | Typed upstream client + fetchGuard + sessions = exactly the BFF kit. |
| API gateway (in-app) | Strong | All the edge concerns, auth, rate limit, CORS, headers, minus traffic proxying. |
| API gateway (standalone, fronting many services) | Not the right tool | Use Kong, APISIX, Envoy, or Tyk. |
| Load balancer | No | Use a real LB (NGINX, HAProxy, ALB, Cloudflare). |
| Server-side renderer (SSR) | No | No JSX/hydration engine. Use Next.js / Remix / Astro and put DaloyJS behind it. |
| Webhook receiver | Excellent | First-party HMAC verifier and signed-payload helpers. |
| WebSocket server | Excellent | First-party app.ws() with CSWSH refuse-to-boot. |
| MCP server (HTTP transport) | Strong | JSON-RPC over HTTP/SSE, DaloyJS handles it; the MCP framing is yours. |
| gRPC server | No | DaloyJS is HTTP/1.1+HTTP/2 REST. Use @grpc/grpc-js. |
| GraphQL server | Possible, not native | You can mount Yoga/Apollo as a single route, but DaloyJS isn't a GraphQL framework. |
| SOAP server | No | SOAP is XML/WSDL; DaloyJS speaks JSON contracts. |
Plain-English definitions
Before we go role-by-role, here is what each term actually means. If you've been nodding along in meetings without being sure, this is for you.
- API server: a process that exposes endpoints (like
GET /books/:id) over HTTP and returns structured data (usually JSON). The thing your mobile app, web app, or another service talks to. - Web server: historically, a process that serves HTML pages, images, and static files to a browser. NGINX and Apache are web servers. An API server is a specialized web server.
- Microservice: one small service that does one thing (orders, payments, search) and talks to others over the network. "Microservice architecture" just means you have many of them instead of one big app.
- Service-to-service (S2S): when two of your own backend services call each other directly, with no human in the loop. Usually authenticated with a shared secret or mTLS, not a user cookie.
- Backend-for-Frontend (BFF): a thin server that sits between a specific frontend (your web app, your iOS app) and your internal APIs. It composes upstream calls, holds the session, and returns exactly the shape the UI needs.
- API gateway: a process at the edge of your network that takes all incoming traffic and routes it to the right internal service. It usually handles auth, rate limiting, request translation, retries, and observability for many services at once.
- Load balancer: a network-level box that takes one stream of requests and spreads them across many identical copies of your service. It cares about TCP connections and health checks, not your routes or schemas.
- Server-side renderer (SSR): a process that turns components (React, Vue, Svelte) into HTML on the server, then ships that HTML to the browser. Next.js, Remix, and Astro are SSR frameworks.
- Webhook receiver: an endpoint that other systems (Stripe, GitHub, Shopify) call to notify your app of events. Usually signed with HMAC so you can verify the sender.
- WebSocket server: a long-lived, bidirectional connection over TCP. Used for chat, live dashboards, multiplayer, collaborative editing.
- MCP server: Model Context Protocol. A standardized way for AI assistants to call tools and read resources. Transports are stdio or HTTP+SSE.
- gRPC: a binary RPC protocol from Google, defined with
.protofiles and running over HTTP/2 with Protobuf encoding. Great for fast, typed S2S inside a cluster. - GraphQL: a query language where the client picks the shape of the response from a single endpoint (usually
POST /graphql). - SOAP: an older XML-based RPC protocol with WSDL contracts. Still common in banking, government, and legacy enterprise.
Role by role
1. API server: the home position
This is what DaloyJS was designed for. You declare a route once, get validation, OpenAPI docs, a typed in-process client, and an autogenerated SDK out the other end.
See Getting started and Routing.
2. Web server (HTML and static files)
DaloyJS can return any Response, so you can serve HTML or files from it. But:
- There's no file-system routing for pages.
- There's no asset pipeline or hydration.
- A CDN will serve static files faster and cheaper.
The only HTML DaloyJS ships out of the box is the Scalar / Swagger docs page at /docs. For real web content, put a CDN, a static host, or Next.js in front and let DaloyJS be the JSON layer.
3. Microservice (one of many)
DaloyJS is a strong fit here, with one small twist: when a service runs behind a mesh, sidecar, or private network, you don't need the browser-only protections like CSRF and same-origin enforcement. The framework ships a preset for exactly this case.
See Internal services & meshes and Modular monolith (you don't need a fleet of services to start).
4. Backend-for-Frontend (BFF): the sweet spot
BFF is arguably where DaloyJS is at its best. The combination you want is all first-party:
- Typed upstream calls via Hey API codegen or the in-process typed client.
- Safe egress via
fetchGuard(), blocks SSRF, private CIDRs, and cloud-metadata IPs by default. - Session edge via
session()(signed cookies, pluggable stores) andcsrf()(double-submit or tokenless Fetch-Metadata). - Streaming to the browser via SSE and NDJSON helpers, plus
compression()with BREACH-aware guards. - Edge runtimes: deploy on Cloudflare, Vercel Edge, Fastly Compute, or Lambda.
Pattern: your Next.js / React Native / iOS app talks only to the BFF; the BFF fans out to internal services and returns exactly what the UI needs.
5. API gateway, strong as "in-app gateway", not a replacement for Kong
DaloyJS gives you almost everything an API gateway does:
- AuthN/Z:
bearerAuth,basicAuth,jwt,jwk,requireScopes - Traffic:
rateLimit(with Redis store),loadShedding,ipRestriction - Edge:
secureHeaders,cors,csrf,compression,etag,requestId - Egress:
fetchGuard(SSRF defaults) - Errors: RFC 9457 problem+json with prod redaction
What it does notdo (and shouldn't):
- No dynamic upstream proxy. There is no
proxyTo("http://upstream"); every route binds to in-process code. - No service discovery, circuit breakers, canary / weighted routing, or traffic mirroring.
- No protocol translation (gRPC ↔ REST, SOAP ↔ REST).
- No declarative gateway config (YAML, CRDs, admin API).
Use it as: the smart edge inside one service, or the front door for a small set of services you also own. Don't use it as: the only gateway sitting in front of a fleet of polyglot microservices. For that, run Kong / APISIX / Tyk / Envoy and put DaloyJS services behind it.
6. Load balancer: no
Load balancing is a TCP-level job. Use NGINX, HAProxy, AWS ALB/NLB, GCP Load Balancing, or Cloudflare. DaloyJS sits behindthe LB and serves requests; it doesn't distribute them. The framework does ship a behindProxy declarative model so it correctly reads X-Forwarded-* headers when the LB terminates TLS.
7. Server-side renderer (SSR): no
There is no JSX, React, Vue, or Svelte renderer in DaloyJS. No renderToString, no hydration, no file-system page router, no React Server Components. The framework deliberately stays in the REST/WS layer.
Recommended pattern: Next.js / Remix / Astro for SSR, DaloyJS for the API behind it. On Vercel you can even mount the same DaloyJS app as a Next.js route handler, see the Vercel adapter.
8. Webhook receiver: excellent
Webhooks are just HTTP POSTs with a signature header. DaloyJS has:
verifyWebhookSignature/signWebhookPayload, zero-knob HMAC helperstimingSafeEqualfor signature comparison- Schema validation on the body
- Body-size limits and prototype-pollution-safe JSON enforced by the core
- RFC 9457 error responses that webhook senders can parse
9. WebSocket server: excellent, with CSWSH guard
First-party WebSocket primitives run on the Node and Bun adapters with a Bun-style handler shape (open, message, close, drain, error).
Under secureDefaults, the framework refuses to register a WebSocket route unless you provide either a pre-upgrade authorization hook or explicitly opt out, and either an Origin allowlist or an explicit acknowledgement. That closes the Cross-Site WebSocket Hijacking (CSWSH) class of bug, cookie auth alone does not protect a WebSocket handshake.
See WebSocket primitives.
10. MCP server (HTTP transport): strong
The Model Context Protocol is JSON-RPC 2.0, transported over either stdio or HTTP + Server-Sent Events. DaloyJS handles the HTTP/SSE half natively:
- Routes for
POST /(JSON-RPC requests) and SSE streaming back - Schema validation on every request
- Bearer auth + scopes for tool authorization
fetchGuardfor any tool that makes outbound HTTP- Streaming helpers at
@daloyjs/core/streaming
You bring the MCP framing (initialize, tools/list, tools/call) on top. DaloyJS won't generate it for you, there's no defineTool() primitive yet, but the HTTP, validation, auth, and SSE pieces are in-box.
11. gRPC server: no
gRPC needs HTTP/2 with Protobuf framing and trailers. DaloyJS is a REST framework around web-standard Request/Response. For gRPC, use @grpc/grpc-js or Connect (which can speak Connect-over-HTTP/1.1 and is friendlier in serverless). You can run a DaloyJS REST gateway in front of a gRPC backend if you want the external surface to be JSON.
12. GraphQL server: possible, not the framework's shape
DaloyJS is contract-first REST: one route, one schema, one OpenAPI operation. GraphQL is one route, one schema, many shapes. They're philosophically different.
If you must, you can mount GraphQL Yoga, Apollo, or Mercurius as a single POST /graphqlroute handler. You'll lose OpenAPI/typed-client benefits for that route. For new projects, either commit to REST (and use DaloyJS) or commit to GraphQL (and use a GraphQL framework).
13. SOAP server: no
SOAP is XML-over-HTTP with WSDL contracts. DaloyJS speaks JSON contracts via Standard Schema. There is no built-in XML parser, no WSDL generator, no SOAP envelope helper. If you have a legacy SOAP client that must talk to you, the practical pattern is: put a small adapter (Java, .NET, or a Node SOAP library like strong-soap) in front, and let it translate to a clean DaloyJS REST API behind.
Cheat sheet: pick the right tool
| If your problem is… | Reach for… | Why not DaloyJS? |
|---|---|---|
| Distribute traffic across N copies of a service | NGINX, HAProxy, ALB, Cloudflare | DaloyJS is the workload, not the router. |
| One front door for 30 polyglot services | Kong, APISIX, Envoy, Tyk | No dynamic upstream proxy or service discovery. |
| Render React/Vue pages on the server | Next.js, Remix, Astro, Nuxt | No component renderer or hydration. |
| Binary, typed, fast S2S RPC inside a cluster | gRPC, Connect | REST/JSON only. |
| Single endpoint, client picks the response shape | GraphQL Yoga, Apollo | Different paradigm; DaloyJS is one-route-per-operation. |
| Old enterprise integration over XML/WSDL | A dedicated SOAP stack (or a translation adapter) | No XML/WSDL primitives. |
| JSON API, validated, documented, secure | DaloyJS | - |
| Webhook receiver with HMAC | DaloyJS | - |
| BFF that composes internal APIs for one UI | DaloyJS | - |
| Real-time chat / dashboards over WS | DaloyJS | - |
| MCP server over HTTP+SSE | DaloyJS (you bring the MCP framing) | - |
A common deployment shape
Most real systems use several of these tools together. A typical production layout looks like this:
Every box marked DaloyJSis the same framework, the same contract style, the same security defaults, just configured for its role. The boxes that aren't DaloyJS exist because they're better at their specific job.