Lambda
Deploy serverless APIs and backend functions on AWS Lambda with API Gateway as the public HTTP endpoint. Scales to zero when idle — pay only for what you use.
Supported Frameworks
AWS Resources
| Resource | Purpose |
|---|---|
| Lambda Function | Runs your server code |
| API Gateway HTTP API | Public HTTP endpoint, routes all traffic to Lambda |
| CloudWatch Logs | Function logs, retained for 1 month |
| ACM Certificate | SSL for custom domain (optional) |
| Route53 | DNS A + AAAA records (optional) |
Serverless API Architecture
Route 53 handles DNS resolution for custom domains. API Gateway manages HTTP requests, authentication, and routing. Lambda executes serverless functions with automatic scaling and pay-per-request pricing.
Quick Start
Installation
bun add -D @thunder-so/thunderConfiguration
import { Cdk, Lambda, type LambdaProps } from '@thunder-so/thunder';
const config: LambdaProps = { env: { account: 'YOUR_ACCOUNT_ID', region: 'us-east-1', }, application: 'myapp', service: 'api', environment: 'prod', rootDir: '.', functionProps: { runtime: Cdk.aws_lambda.Runtime.NODEJS_22_X, architecture: Cdk.aws_lambda.Architecture.ARM_64, codeDir: 'dist', handler: 'index.handler', memorySize: 512, timeout: 10, },};
new Lambda( new Cdk.App(), `${config.application}-${config.service}-${config.environment}-stack`, config);Deploy
bun run buildnpx cdk deploy --app "bunx tsx stack/prod.ts" --profile defaultCDK outputs the API Gateway URL:
Outputs:myapp-api-prod-stack.ApiGatewayUrl = https://abc123.execute-api.us-east-1.amazonaws.comCustom Domain
Connect your API to a custom domain. The certificate must be issued in the same region as your Lambda function — unlike Static, Lambda uses a regional (not global) certificate.
const config: LambdaProps = { // ... domain: 'api.example.com', hostedZoneId: 'Z1D633PJN98FT9', regionalCertificateArn: 'arn:aws:acm:us-east-1:123456789012:certificate/abc-123',};Advanced Configuration
Performance and Concurrency
Fine-tune your function’s performance with memory, timeout, and concurrency settings. Memory also controls proportional CPU allocation.
const config: LambdaProps = { // ... functionProps: { runtime: Cdk.aws_lambda.Runtime.NODEJS_22_X, architecture: Cdk.aws_lambda.Architecture.ARM_64, memorySize: 1792, // more memory = more CPU timeout: 10, tracing: true, // enable AWS X-Ray keepWarm: true, // ping every 5 min to prevent cold starts reservedConcurrency: 10, // hard cap on simultaneous executions provisionedConcurrency: 2, // pre-warmed instances, eliminates cold starts url: true, // also expose a direct Lambda Function URL },};Environment Variables and Secrets
const config: LambdaProps = { // ... functionProps: { variables: [ { NODE_ENV: 'production' }, { API_URL: 'https://api.example.com' }, ], secrets: [ { key: 'DATABASE_URL', resource: 'arn:aws:secretsmanager:us-east-1:123456789012:secret:/myapp/DATABASE_URL-abc123', }, ], },};Thunder automatically grants the Lambda execution role secretsmanager:GetSecretValue on each referenced secret.
Container Deployments
Deploy Lambda functions as container images to use custom runtimes, package large dependencies, or exceed the 250 MB zip limit. Container images support up to 10 GB.
Node.js Container
FROM public.ecr.aws/lambda/nodejs:22 AS builderWORKDIR ${LAMBDA_TASK_ROOT}COPY . .RUN npm ciRUN npm run build
FROM public.ecr.aws/lambda/nodejs:22WORKDIR ${LAMBDA_TASK_ROOT}COPY --from=builder /var/task/dist/* ./COPY --from=builder /var/task/node_modules ./node_modulesCMD ["index.handler"]const config: LambdaProps = { // ... functionProps: { dockerFile: 'Dockerfile', memorySize: 1792, keepWarm: true, },};Bun Runtime Container
Bun is not a managed Lambda runtime, so it runs as a container. The bootstrap binary handles the Lambda runtime protocol and forwards requests to your Bun fetch handler.
# Stage 1: Build the Bun Lambda bootstrapFROM oven/bun:latest AS bunWORKDIR /tmpRUN apt-get update && apt-get install -y curlRUN curl -fsSL https://raw.githubusercontent.com/oven-sh/bun/main/packages/bun-lambda/runtime.ts -o runtime.tsRUN bun install aws4fetchRUN bun build --compile runtime.ts --outfile bootstrap
# Stage 2: Build your appFROM oven/bun:latest AS builderWORKDIR /tmpCOPY . .RUN bun installRUN bun run build
# Stage 3: Runtime imageFROM public.ecr.aws/lambda/provided:al2023WORKDIR ${LAMBDA_TASK_ROOT}COPY --from=bun /tmp/bootstrap ${LAMBDA_RUNTIME_DIR}COPY --from=builder /tmp/dist/ ./COPY --from=builder /tmp/node_modules ./node_modulesCMD ["lambda-bun.fetch"]const config: LambdaProps = { // ... functionProps: { dockerFile: 'Dockerfile.bun', memorySize: 512, keepWarm: true, },};CI/CD Pipeline
Zip Deployment Pipeline
GitHub triggers deployments on code changes. CodePipeline orchestrates the workflow while CodeBuild packages the function code into a zip file and deploys directly to Lambda.
const config: LambdaProps = { // ... accessTokenSecretArn: 'arn:aws:secretsmanager:us-east-1:123456789012:secret:github-token-XXXXXX', sourceProps: { owner: 'your-username', repo: 'your-repo', branchOrRef: 'main', }, buildProps: { runtime: 'nodejs', runtime_version: '22', installcmd: 'bun install', buildcmd: 'bun run build', outputDir: 'dist', },};Container Deployment Pipeline
GitHub triggers deployments. CodeBuild builds Docker images with custom runtimes, pushes to ECR, then deploys container images to Lambda for advanced use cases requiring custom dependencies or alternative runtimes like Bun.
const config: LambdaProps = { // ... accessTokenSecretArn: 'arn:aws:secretsmanager:us-east-1:123456789012:secret:github-token-XXXXXX', sourceProps: { owner: 'your-username', repo: 'your-repo', branchOrRef: 'main', }, functionProps: { dockerFile: 'Dockerfile', }, buildProps: { installcmd: 'bun install', buildcmd: 'bun run build', },};Stack Outputs
| Output | Description |
|---|---|
ApiGatewayUrl | API Gateway endpoint URL |
LambdaFunction | Lambda function name |
LambdaFunctionUrl | Direct Lambda URL (only if url: true) |
Route53Domain | Custom domain URL (only if domain is configured) |
Destroy
npx cdk destroy --app "bunx tsx stack/prod.ts" --profile default