# AWS Lambda

The Lambda adapter accepts **API Gateway HTTP API payload v2.0**, **API Gateway REST API payload v1.0**, and **Lambda Function URLs** without configuration. It handles base64 bodies, v2 `cookies`, v1 `multiValueHeaders`, and forwards method, path, query, and headers into a standard `Request`.

**Diagram: Lambda adapter request path**

- **HTTP API v2 · REST v1 · Function URL** (trigger) - Lambda event payload
- **toLambdaHandler(app)** (adapter) - decodes base64, cookies, multiValueHeaders
- **app.fetch(Request)** (core) - routing · hooks · handler
- **Lambda result** (trigger) - or streamed via toLambdaStreamHandler

toLambdaHandler normalizes all three event shapes into one web-standard Request, runs app.fetch, then serializes the Response back into the Lambda result. Swap in toLambdaStreamHandler for SSE or large downloads.

## When to choose Lambda

- You already run on AWS and want IAM-integrated invocation.
- You want per-request billing without managing a server.
- You need long timeouts (up to 15 minutes) or larger memory than edge functions allow.

## Install

The adapter ships with `@daloyjs/core`. For deployment, use AWS SAM, CDK, the Serverless Framework, or any IaC of your choice.

## Function URL or API Gateway HTTP API

```ts
// src/lambda.ts
import { toLambdaHandler } from "@daloyjs/core/lambda";
import { app } from "./server.js";

export const handler = toLambdaHandler(app);
```

## Streaming responses

Lambda supports response streaming via `awslambda.streamifyResponse`. Use the streaming variant of the adapter when you need to flush headers and bytes incrementally (Server-Sent Events, large downloads).

```ts
// src/lambda-stream.ts
import { toLambdaStreamHandler } from "@daloyjs/core/lambda";
import { app } from "./server.js";

export const handler = toLambdaStreamHandler(app);
// Uses awslambda.streamifyResponse + HttpResponseStream.from internally.
```

## SAM template

DaloyJS requires Node 24 LTS or Node 26+ (`engines.node: "^24.0.0 || >=26.0.0"`). Use the `nodejs24.x` managed runtime where available, or ship a container image (see Lambda Web Adapter below) if your region's runtime catalog is older.

```yaml
# template.yaml
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31

Resources:
  Api:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: dist/
      Handler: lambda.handler
      Runtime: nodejs24.x
      MemorySize: 1024
      Timeout: 30
      FunctionUrlConfig:
        AuthType: NONE
        InvokeMode: BUFFERED   # or RESPONSE_STREAM for streaming
```

## Lambda Web Adapter (container deployments)

If you prefer to ship a container image and keep the Node adapter, the [AWS Lambda Web Adapter](https://github.com/awslabs/aws-lambda-web-adapter) translates Lambda invocations to plain HTTP. Useful when you want one image for both ECS and Lambda.

```docker
FROM public.ecr.aws/awsguru/aws-lambda-adapter:0.9.0 AS adapter
FROM node:24-slim
COPY --from=adapter /lambda-adapter /opt/extensions/lambda-adapter
WORKDIR /var/task
COPY package.json pnpm-lock.yaml ./
RUN corepack enable && pnpm install --prod --frozen-lockfile
COPY dist ./dist
ENV PORT=8080 AWS_LWA_PORT=8080
CMD ["node", "dist/server.js"]
```

## Gotchas

- Callback-style handlers (`(event, context, callback) => ...`) are not supported on supported Node versions. Always use `async` handlers; the DaloyJS adapter does.
- For Function URLs with streaming, set `InvokeMode: RESPONSE_STREAM` and use `toLambdaStreamHandler`.
- Cold starts: prefer the Node adapter on provisioned concurrency or use a container with the Web Adapter for warmer reuse.

## See also

- [Adapters overview](/docs/adapters)
- [Netlify Functions](/docs/adapters/netlify): v1 still uses the same Lambda event shape if you need it.
- [Streaming (SSE & NDJSON)](/docs/streaming)

---

Source: https://daloyjs.dev/docs/adapters/aws-lambda