srvx provides an AWS Lambda compatibility adapter that handles all the necessary transformations between AWS Lambda's event format and standard web Request/Response objects.
To use the AWS Lambda adapter, import the toLambdaHandler function from "srvx/aws-lambda":
import { toLambdaHandler } from "srvx/aws-lambda";
import { serveStatic } from "srvx/static";
export const handler = toLambdaHandler({
middleware: [serveStatic({ dir: "public" })],
fetch(req: Request) {
return Response.json({ hello: "world!" });
},
});
The toLambdaHandler function accepts a ServerOptions object as its parameter (see Server Options for details). However, since this is a serverless environment, options related to the server instance like host and port are not respected and will be ignored.
You can find a complete example of AWS Lambda in the examples/aws-lambda directory.
The example above uses serveStatic middleware to serve static files directly from the Lambda function. While this works for simple use cases, it comes with limitations:
For production applications, consider these alternatives:
The invokeLambdaHandler utility allows you to invoke an AWS Lambda handler using standard Web Request/Response objects. This is useful for testing your Lambda handlers locally or integrating them into other web-based workflows.
import { toLambdaHandler, invokeLambdaHandler } from "srvx/aws-lambda";
const handler = toLambdaHandler({
fetch(req: Request) {
return Response.json({ hello: "world!" });
},
});
// Invoke the handler with a standard Request
const request = new Request("https://example.com/api");
const response = await invokeLambdaHandler(handler, request);
console.log(await response.json()); // { hello: "world!" }
The function handles all conversions internally:
Request to an AWS Lambda event (compatible with both v1 and v2 API Gateway formats)ResponseAWS Lambda supports response streaming which allows you to send response data progressively as it becomes available. This improves Time To First Byte (TTFB) and enables streaming large responses (up to 20MB vs 6MB buffered limit).
To use response streaming, wrap your handler with awslambda.streamifyResponse() and use handleLambdaEventWithStream:
import { handleLambdaEventWithStream, type AWSLambdaStreamingHandler } from "srvx/aws-lambda";
const fetchHandler = async (request: Request) => {
// Create a streaming response
const stream = new ReadableStream({
async start(controller) {
controller.enqueue(new TextEncoder().encode("Hello, "));
await new Promise((r) => setTimeout(r, 100));
controller.enqueue(new TextEncoder().encode("streaming "));
await new Promise((r) => setTimeout(r, 100));
controller.enqueue(new TextEncoder().encode("world!"));
controller.close();
},
});
return new Response(stream, {
headers: { "Content-Type": "text/plain" },
});
};
// Export a streaming handler
export const handler: AWSLambdaStreamingHandler = awslambda.streamifyResponse(
(event, responseStream, context) =>
handleLambdaEventWithStream(fetchHandler, event, responseStream, context),
);
--invoke-mode RESPONSE_STREAM or the InvokeWithResponseStream API. It does not work with API Gateway or Application Load Balancer for progressive streaming.