Deploy transpiled TypeScript code in Lambda with .zip file archives
Before you can deploy TypeScript code to AWS Lambda, you need to transpile it into JavaScript. This page explains three ways to build and deploy TypeScript code to Lambda with .zip file archives:
AWS SAM and AWS CDK simplify building and deploying TypeScript functions. The AWS SAM template specification provides a simple and clean syntax to describe the Lambda functions, APIs, permissions, configurations, and events that make up your serverless application. The AWS CDK lets you build reliable, scalable, cost-effective applications in the cloud with the considerable expressive power of a programming language. The AWS CDK is intended for moderately to highly experienced AWS users. Both the AWS CDK and the AWS SAM use esbuild to transpile TypeScript code into JavaScript.
Using AWS SAM to deploy TypeScript code to Lambda
Follow the steps below to download, build, and deploy a sample Hello World TypeScript application using the AWS SAM. This application implements a basic API backend. It consists of an Amazon API Gateway endpoint and a Lambda function. When you send a GET request to the API Gateway endpoint, the Lambda function is invoked. The function returns a hello world
message.
Note
AWS SAM uses esbuild to create Node.js Lambda functions from TypeScript code. esbuild support is currently in public preview. During public preview, esbuild support may be subject to backwards incompatible changes.
Prerequisites
To complete the steps in this section, you must have the following:
-
Node.js 18.x
Deploy a sample AWS SAM application
-
Initialize the application using the Hello World TypeScript template.
sam init --app-template hello-world-typescript --name sam-app --package-type Zip --runtime nodejs18.x
-
(Optional) The sample application includes configurations for commonly used tools, such as ESLlint
for code linting and Jest for unit testing. To run lint and test commands: cd sam-app/hello-world npm install npm run lint npm run test
-
Build the app.
cd sam-app sam build
-
Deploy the app.
sam deploy --guided
-
Follow the on-screen prompts. To accept the default options provided in the interactive experience, respond with
Enter
. -
The output shows the endpoint for the REST API. Open the endpoint in a browser to test the function. You should see this response:
{"message":"hello world"}
-
This is a public API endpoint that is accessible over the internet. We recommend that you delete the endpoint after testing.
sam delete
Using the AWS CDK to deploy TypeScript code to Lambda
Follow the steps below to build and deploy a sample TypeScript application using the AWS CDK. This application implements a basic API backend. It consists of an API Gateway endpoint and a Lambda function. When you send a GET request to the API Gateway endpoint, the Lambda function is invoked. The function returns a hello world
message.
Prerequisites
To complete the steps in this section, you must have the following:
-
Node.js 18.x
Deploy a sample AWS CDK application
-
Create a project directory for your new application.
mkdir hello-world cd hello-world
-
Initialize the app.
cdk init app --language typescript
-
Add the @types/aws-lambda
package as a development dependency. This package contains the type definitions for Lambda. npm install -D @types/aws-lambda
-
Open the lib directory. You should see a file called hello-world-stack.ts. Create two new files in this directory: hello-world.function.ts and hello-world.ts.
-
Open hello-world.function.ts and add the following code to the file. This is the code for the Lambda function.
Note
The
import
statement imports the type definitions from @types/aws-lambda. It does not import the aws-lambda
NPM package, which is an unrelated third-party tool. For more information, see aws-lambdain the DefinitelyTyped GitHub repository. import { Context, APIGatewayProxyResult, APIGatewayEvent } from 'aws-lambda'; export const handler = async (event: APIGatewayEvent, context: Context): Promise<APIGatewayProxyResult> => { console.log(`Event: ${JSON.stringify(event, null, 2)}`); console.log(`Context: ${JSON.stringify(context, null, 2)}`); return { statusCode: 200, body: JSON.stringify({ message: 'hello world', }), }; };
-
Open hello-world.ts and add the following code to the file. This contains the NodejsFunction construct, which creates the Lambda function, and the LambdaRestApi construct, which creates the REST API.
import { Construct } from 'constructs'; import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs'; import { LambdaRestApi } from 'aws-cdk-lib/aws-apigateway'; export class HelloWorld extends Construct { constructor(scope: Construct, id: string) { super(scope, id); const helloFunction = new NodejsFunction(this, 'function'); new LambdaRestApi(this, 'apigw', { handler: helloFunction, }); } }
The
NodejsFunction
construct assumes the following by default:-
Your function handler is called
handler
. -
The .ts file that contains the function code (hello-world.function.ts) is in the same directory as the .ts file that contains the construct (hello-world.ts). The construct uses the construct's ID ("hello-world") and the name of the Lambda handler file ("function") to find the function code. For example, if your function code is in a file called hello-world.my-function.ts, the hello-world.ts file must reference the function code like this:
const helloFunction = new NodejsFunction(this,
'my-function'
);
You can change this behavior and configure other esbuild parameters. For more information, see Configuring esbuild in the AWS CDK API reference.
-
-
Open hello-world-stack.ts. This is the code that defines your AWS CDK stack. Replace the code with the following:
import { Stack, StackProps } from 'aws-cdk-lib'; import { Construct } from 'constructs'; import { HelloWorld } from './hello-world'; export class HelloWorldStack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); new HelloWorld(this, 'hello-world'); } }
-
from the
hello-world
directory containing yourcdk.json
file, deploy your application.cdk deploy
-
The AWS CDK builds and packages the Lambda function using esbuild, and then deploys the function to the Lambda runtime. The output shows the endpoint for the REST API. Open the endpoint in a browser to test the function. You should see this response:
{"message":"hello world"}
This is a public API endpoint that is accessible over the internet. We recommend that you delete the endpoint after testing.
Using the AWS CLI and esbuild to deploy TypeScript code to Lambda
The following example demonstrates how to transpile and deploy TypeScript code to Lambda using esbuild and the AWS CLI. esbuild produces one JavaScript file with all dependencies. This is the only file that you need to add to the .zip archive.
Prerequisites
To complete the steps in this section, you must have the following:
-
Node.js 18.x
-
An execution role for the Lambda function
-
For Windows users, a zip file utility such as 7zip
.
Deploy a sample function
-
On your local machine, create a project directory for your new function.
-
Create a new Node.js project with npm or a package manager of your choice.
npm init
-
Add the @types/aws-lambda
and esbuild packages as development dependencies. The @types/aws-lambda
package contains the type definitions for Lambda.npm install -D @types/aws-lambda esbuild
-
Create a new file called index.ts. Add the following code to the new file. This is the code for the Lambda function. The function returns a
hello world
message. The function doesn’t create any API Gateway resources.Note
The
import
statement imports the type definitions from @types/aws-lambda. It does not import the aws-lambda
NPM package, which is an unrelated third-party tool. For more information, see aws-lambdain the DefinitelyTyped GitHub repository. import { Context, APIGatewayProxyResult, APIGatewayEvent } from 'aws-lambda'; export const handler = async (event: APIGatewayEvent, context: Context): Promise<APIGatewayProxyResult> => { console.log(`Event: ${JSON.stringify(event, null, 2)}`); console.log(`Context: ${JSON.stringify(context, null, 2)}`); return { statusCode: 200, body: JSON.stringify({ message: 'hello world', }), }; };
-
Add a build script to the package.json file. This configures esbuild to automatically create the .zip deployment package. For more information, see Build scripts
in the esbuild documentation. -
Build the package.
npm run build
-
Create a Lambda function using the .zip deployment package. Replace the highlighted text with the Amazon Resource Name (ARN) of your execution role.
aws lambda create-function --function-name hello-world --runtime "nodejs18.x" --role
arn:aws:iam::123456789012:role/lambda-ex
--zip-file "fileb://dist/index.zip" --handler index.handler -
Run a test event to confirm that the function returns the following response. If you want to invoke this function using API Gateway, create and configure a REST API.
{ "statusCode": 200, "body": "{\"message\":\"hello world\"}" }