Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/honojs/hono/llms.txt

Use this file to discover all available pages before exploring further.

The AWS Lambda adapter converts Hono applications into AWS Lambda handlers that work with API Gateway, ALB, Lambda Function URLs, and VPC Lattice.

Import

import { 
  handle, 
  streamHandle, 
  defaultIsContentTypeBinary, 
  getConnInfo 
} from 'hono/aws-lambda'
import type { 
  LambdaEvent, 
  APIGatewayProxyResult,
  ApiGatewayRequestContext,
  ApiGatewayRequestContextV2,
  ALBRequestContext,
  LambdaContext
} from 'hono/aws-lambda'

Functions

handle()

Converts a Hono application to an AWS Lambda handler. Accepts events from API Gateway (v1 and v2), Application Load Balancer (ALB), Lambda Function URLs, and VPC Lattice.
function handle<E extends Env, S extends Schema, BasePath extends string>(
  app: Hono<E, S, BasePath>,
  options?: HandleOptions
): LambdaHandler

Parameters

  • app - The Hono application instance
  • options - Optional configuration:
    • isContentTypeBinary - (contentType: string) => boolean - Function to determine if content should be base64 encoded

Returns

Lambda handler function compatible with API Gateway, ALB, and Function URLs.

Example

import { Hono } from 'hono'
import { handle } from 'hono/aws-lambda'

const app = new Hono()

app.get('/', (c) => c.text('Hello from Lambda!'))
app.post('/api/users', async (c) => {
  const body = await c.req.json()
  return c.json({ success: true, data: body })
})

app.get('/image', (c) => {
  // Binary responses are automatically base64 encoded
  return c.body(imageBuffer, 200, {
    'Content-Type': 'image/png'
  })
})

export const handler = handle(app)

Custom Binary Content Detection

import { handle, defaultIsContentTypeBinary } from 'hono/aws-lambda'

export const handler = handle(app, {
  isContentTypeBinary: (contentType) => {
    // Use default logic
    if (defaultIsContentTypeBinary(contentType)) {
      return true
    }
    // Add custom binary types
    return contentType.startsWith('image/') || 
           contentType === 'application/pdf' ||
           contentType === 'application/zip'
  }
})

streamHandle()

Creates a streaming Lambda handler that uses response streaming for better performance with large responses.
function streamHandle<E extends Env, S extends Schema, BasePath extends string>(
  app: Hono<E, S, BasePath>
): StreamingLambdaHandler
Streaming responses require Lambda function URLs or API Gateway HTTP APIs configured for streaming. This feature requires the AWS Lambda runtime to support response streaming.

Example

import { Hono } from 'hono'
import { streamHandle } from 'hono/aws-lambda'

const app = new Hono()

app.get('/large-data', async (c) => {
  // Stream large responses efficiently
  const stream = new ReadableStream({
    start(controller) {
      for (let i = 0; i < 10000; i++) {
        controller.enqueue(`Line ${i}\n`)
      }
      controller.close()
    }
  })
  return c.body(stream)
})

export const handler = streamHandle(app)

defaultIsContentTypeBinary()

Default function to determine if a content type should be base64 encoded.
function defaultIsContentTypeBinary(contentType: string): boolean

Returns

true if the content type is binary, false otherwise.

Logic

Returns false for:
  • text/* (text/plain, text/html, text/css, text/javascript, text/csv)
  • Content types containing json or xml (including application/json, application/xml, +json, +xml)
Returns true for all other content types.

getConnInfo()

Extracts connection information from AWS Lambda events.
function getConnInfo(c: Context): ConnInfo
Works with multiple event sources:
  • API Gateway v1 (REST API): requestContext.identity.sourceIp
  • API Gateway v2 (HTTP API/Function URLs): requestContext.http.sourceIp
  • ALB: Falls back to x-forwarded-for header

Returns

interface ConnInfo {
  remote: {
    address?: string  // Client IP address
  }
}

Example

import { Hono } from 'hono'
import { handle, getConnInfo } from 'hono/aws-lambda'

const app = new Hono()

app.get('/', (c) => {
  const info = getConnInfo(c)
  return c.text(`Your IP: ${info.remote.address}`)
})

app.get('/request-info', (c) => {
  const info = getConnInfo(c)
  const requestContext = c.env.requestContext
  
  return c.json({
    ip: info.remote.address,
    requestId: requestContext.requestId,
    stage: 'stage' in requestContext ? requestContext.stage : undefined
  })
})

export const handler = handle(app)

Types

LambdaEvent

Union type of all supported Lambda event types:
type LambdaEvent = 
  | APIGatewayProxyEvent      // API Gateway REST API (v1)
  | APIGatewayProxyEventV2    // API Gateway HTTP API (v2) / Function URLs
  | ALBProxyEvent             // Application Load Balancer
  | LatticeProxyEventV2       // VPC Lattice

APIGatewayProxyResult

Lambda response format for API Gateway:
type APIGatewayProxyResult = {
  statusCode: number
  statusDescription?: string
  body: string
  cookies?: string[]           // API Gateway v2 only
  isBase64Encoded: boolean
} & (WithHeaders | WithMultiValueHeaders)

Request Context Types

ApiGatewayRequestContext

API Gateway REST API (v1) request context:
interface ApiGatewayRequestContext {
  accountId: string
  apiId: string
  domainName: string
  httpMethod: string
  identity: Identity
  path: string
  requestId: string
  stage: string
  // ... additional fields
}

ApiGatewayRequestContextV2

API Gateway HTTP API (v2) and Function URLs request context:
interface ApiGatewayRequestContextV2 {
  accountId: string
  apiId: string
  domainName: string
  http: {
    method: string
    path: string
    protocol: string
    sourceIp: string
    userAgent: string
  }
  requestId: string
  routeKey: string
  stage: string
  // ... additional fields
}

ALBRequestContext

Application Load Balancer request context:
interface ALBRequestContext {
  elb: {
    targetGroupArn: string
  }
}

LambdaContext

AWS Lambda runtime context:
interface LambdaContext {
  callbackWaitsForEmptyEventLoop: boolean
  functionName: string
  functionVersion: string
  invokedFunctionArn: string
  memoryLimitInMB: string
  awsRequestId: string
  logGroupName: string
  logStreamName: string
  identity?: CognitoIdentity
  clientContext?: ClientContext
  getRemainingTimeInMillis(): number
}

Accessing Lambda Context

The Lambda event and context are available through c.env:
import { Hono } from 'hono'
import { handle } from 'hono/aws-lambda'
import type { LambdaEvent, LambdaContext } from 'hono/aws-lambda'

type Bindings = {
  event: LambdaEvent
  requestContext: ApiGatewayRequestContextV2
  lambdaContext: LambdaContext
}

const app = new Hono<{ Bindings: Bindings }>()

app.get('/lambda-info', (c) => {
  const { lambdaContext } = c.env
  
  return c.json({
    functionName: lambdaContext.functionName,
    requestId: lambdaContext.awsRequestId,
    remainingTime: lambdaContext.getRemainingTimeInMillis(),
    memoryLimit: lambdaContext.memoryLimitInMB
  })
})

export const handler = handle(app)

Platform-Specific Notes

Event Sources

The adapter automatically detects and handles:
  • API Gateway REST API (v1): Traditional REST APIs with resource-based routing
  • API Gateway HTTP API (v2): Lower latency, lower cost HTTP APIs
  • Lambda Function URLs: Direct HTTPS endpoints for Lambda functions
  • Application Load Balancer: ALB target integrations
  • VPC Lattice: Service mesh integrations

Binary Content

Binary responses are automatically base64 encoded based on:
  1. Content-Type header (via isContentTypeBinary option)
  2. Content-Encoding header (gzip, deflate, compress, br)

Headers

  • Single-value headers: Used by default and API Gateway v2
  • Multi-value headers: Used when the event includes multiValueHeaders

Cookies

  • API Gateway v2: Uses the cookies array in the response
  • API Gateway v1: Uses multiValueHeaders['set-cookie']
  • ALB: Depends on multi-value headers configuration

Deployment

Using AWS SAM

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

Resources:
  HonoFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: nodejs20.x
      Events:
        ApiEvent:
          Type: HttpApi
          Properties:
            Path: /{proxy+}
            Method: ANY

Using AWS CDK

import * as lambda from 'aws-cdk-lib/aws-lambda'
import * as apigateway from 'aws-cdk-lib/aws-apigatewayv2'
import { HttpLambdaIntegration } from 'aws-cdk-lib/aws-apigatewayv2-integrations'

const handler = new lambda.Function(this, 'HonoHandler', {
  runtime: lambda.Runtime.NODEJS_20_X,
  code: lambda.Code.fromAsset('dist'),
  handler: 'index.handler',
})

const httpApi = new apigateway.HttpApi(this, 'HonoApi', {
  defaultIntegration: new HttpLambdaIntegration('HonoIntegration', handler),
})

Using Serverless Framework

# serverless.yml
service: hono-lambda

provider:
  name: aws
  runtime: nodejs20.x

functions:
  api:
    handler: index.handler
    events:
      - httpApi:
          path: /{proxy+}
          method: ANY

See Also