Node-Style vs Web Standard Middleware Signatures in SXO
SXO supports two distinct middleware APIs—Node-style (req, res, next) for local CLI servers and Web Standard (request, env) => Response for portable edge runtimes—allowing the same framework to run in both Node.js and serverless environments.
The SXO framework (gc-victor/sxo) bridges traditional Node.js HTTP servers and modern Web Standard runtimes by providing dual middleware interfaces. Understanding the difference between Node-style and Web Standard middleware signatures ensures your middleware runs correctly whether you're using sxo dev locally or deploying to Cloudflare Workers.
Node-Style Middleware Signature
Function Signature and Return Values
Node-style middleware uses the signature (req, res, next) => void or (req, res) => boolean. According to the README (lines 29-33), this API accepts the raw Node.js http.IncomingMessage and http.ServerResponse objects. The function may call next() to continue the chain, return true or false to indicate request handling status, or terminate the response directly via res.end().
When to Use Node-Style Middleware
This signature is exclusive to the CLI server context used by sxo dev and sxo start commands. It executes within the local Node.js process that handles raw HTTP primitives, making it ideal for quick local development, custom logging, or features requiring direct socket access such as TCP upgrades.
Implementation Example
The loader in src/js/server/middleware.js discovers user-defined middleware and invokes each function with the Node request-response pair:
// src/middleware.js – Node-style example
export default function (req, res, next) {
// Simple health-check endpoint
if (req.url === "/ping") {
res.end("pong"); // handle the request
return; // stop further processing
}
next(); // continue to the next middleware / route
}
Web Standard Middleware Signature
Function Signature and Return Values
Web Standard middleware implements the Fetch API signature (request: Request, env?: object) => Response | void | Promise<Response | void>. As documented in the README (lines 46-50), this function receives a standard Request object and an optional env object containing platform bindings or secrets. Returning a Response short-circuits the middleware chain immediately, while returning void allows the request to continue.
When to Use Web Standard Middleware
This signature is required for platform adapters such as Cloudflare Workers, Bun, Deno, and SXO's internal production adapters. The runtime in src/js/runtime/middleware.js re-exports the executeMiddleware executor from src/js/runtime/handler.js, which iterates over the middleware array expecting Web Standard objects. This approach ensures your code remains portable across all serverless runtimes that implement the Fetch API standard.
Implementation Example
The runtime executor awaits each middleware call, handling promises and response short-circuiting automatically:
// src/middleware.js – Web Standard example
export default async function (request, env) {
const url = new URL(request.url);
// Short-circuit the request with a Response
if (url.pathname === "/ping") {
return new Response("pong", { status: 200 });
}
// Returning nothing lets the request continue to the next middleware / route
}
Core Implementation Files in SXO
The framework maintains separate loaders and executors to handle both signatures:
-
src/js/server/middleware.js— Contains the loader that discovers user-defined middleware. The comment block at lines 5-7 explicitly defines the expected "Web Standard middleware functions" signature, while the implementation handles the discovery and loading logic for both development and production contexts. -
src/js/runtime/middleware.js— Re-exports theexecuteMiddlewareexecutor (lines 11-12) used by platform adapters. This module processes the Web Standard middleware chain for Cloudflare Workers and other edge runtimes. -
src/js/server/prod/node.js— Implements the production Node.js adapter. Lines 69-76 demonstrate how the framework callsloadUserDefinedMiddlewares()to load user middleware, then converts the Nodereqobject to a Web StandardRequestviatoWebRequest(req, PORT)before execution. This conversion allows the same middleware array to function across both Node and Web Standard environments.
Summary
- Node-style middleware uses
(req, res, next)and runs only in the local CLI server (sxo dev,sxo start) with direct access to Node.js HTTP primitives. - Web Standard middleware uses
(request, env) => Responseand runs in all platform adapters including Cloudflare Workers, Bun, and Deno, utilizing portable Fetch API objects. - The production Node adapter in
src/js/server/prod/node.jsconverts incoming requests to Web Standard format before executing middleware, ensuring cross-platform compatibility. - Both middleware types are registered in
src/js/server/middleware.js, but executed by different runtimes depending on the deployment target.
Frequently Asked Questions
Can I use Node-style middleware in Cloudflare Workers?
No. Cloudflare Workers and other edge runtimes do not expose Node.js http modules. These environments exclusively use the Web Standard signature processed by src/js/runtime/middleware.js, which expects Request and Response objects rather than http.IncomingMessage and http.ServerResponse.
Does SXO automatically convert between Node and Web Standard formats?
Yes. According to src/js/server/prod/node.js, the production Node adapter automatically converts incoming Node requests to Web Standard Request objects using the internal toWebRequest(req, PORT) utility. This conversion happens before the middleware chain executes, allowing Web Standard middleware to run unchanged in Node.js production environments.
Which signature should I use for new projects?
Use the Web Standard signature (request, env) for maximum portability. This ensures your middleware runs on Cloudflare Workers, Bun, Deno, and SXO's production adapters without modification. Only use Node-style middleware when you specifically require direct access to raw Node.js HTTP primitives for local development tasks.
What happens if middleware returns a Response in Web Standard mode?
Returning a Response object immediately short-circuits the middleware chain and sends that response to the client. If middleware returns void or undefined, the runtime executor continues to the next middleware function or route handler. This behavior is implemented in the executeMiddleware function exported from src/js/runtime/handler.js and re-exported via src/js/runtime/middleware.js.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →