Skip to content

Function

Reference doc for the `sst.aws.Function` component.

The Function component lets you add serverless functions to your app. It uses AWS Lambda.

Minimal example

Pass in the path to your handler function.

sst.config.ts
new sst.aws.Function("MyFunction", {
handler: "src/lambda.handler"
});

Set additional config

Pass in additional Lambda config.

sst.config.ts
new sst.aws.Function("MyFunction", {
handler: "src/lambda.handler",
timeout: "3 minutes",
memory: "1024 MB"
});

Link resources to the function. This will grant permissions to the resources and allow you to access it in your handler.

sst.config.ts
const bucket = new sst.aws.Bucket("MyBucket");
new sst.aws.Function("MyFunction", {
handler: "src/lambda.handler",
link: [bucket]
});

You can use the SDK to access the linked resources in your handler.

src/lambda.ts
import { Resource } from "sst";
console.log(Resource.MyBucket.name);

Set environment variables

Set environment variables for the function. Available in your handler as process.env.

sst.config.ts
new sst.aws.Function("MyFunction", {
handler: "src/lambda.handler",
environment: {
DEBUG: "true"
}
});

Enable function URLs

Enable function URLs to invoke the function over HTTP.

sst.config.ts
new sst.aws.Function("MyFunction", {
handler: "src/lambda.handler",
url: true
});

Bundling

Customize how SST uses esbuild to bundle your function code with the nodejs property.

sst.config.ts
new sst.aws.Function("MyFunction", {
handler: "src/lambda.handler",
nodejs: {
install: ["pg"]
}
});

Or override it entirely by passing in your own function bundle.


Constructor

new Function(name, args, opts?)

Parameters

FunctionArgs

architecture?

Type Input<x86_64 | arm64>

Default “x86_64”

The architecture of the Lambda function.

{
architecture: "arm64"
}

bundle?

Type Input<string>

Path to the source code directory for the function. By default, the handler is bundled with esbuild. Use bundle to skip bundling.

If the bundle option is specified, the handler needs to be in the root of the bundle.

Here, the entire packages/functions/src directory is zipped. And the handler is in the src directory.

{
bundle: "packages/functions/src",
handler: "index.handler"
}

concurrency?

Type Input<Object>

Default No concurrency settings set

Configure the concurrency settings for the function.

{
concurrency: {
provisioned: 10,
reserved: 50
}
}

concurrency.provisioned?

Type Input<number>

Default No provisioned concurrency

Provisioned concurrency ensures a specific number of Lambda instances are always ready to handle requests, reducing cold start times. Enabling this will incur extra charges.

Note that versioning needs to be enabled for provisioned concurrency.

{
concurrency: {
provisioned: 10
}
}

concurrency.reserved?

Type Input<number>

Default No reserved concurrency

Reserved concurrency limits the maximum number of concurrent executions for a function, ensuring critical functions always have capacity. It does not incur extra charges.

{
concurrency: {
reserved: 50
}
}

copyFiles?

Type Input<Object[]>

Add additional files to copy into the function package. Takes a list of objects with from and to paths. These will be copied over before the function package is zipped up.

Copying over a single file from the src directory to the src/ directory of the function package.

{
copyFiles: [{ from: "src/index.js" }]
}

Copying over a single file from the src directory to the core/src directory in the function package.

{
copyFiles: [{ from: "src/index.js", to: "core/src/index.js" }]
}

Copying over a couple of files.

{
copyFiles: [
{ from: "src/this.js", to: "core/src/this.js" },
{ from: "src/that.js", to: "core/src/that.js" }
]
}

copyFiles[].from

Type Input<string>

Source path relative to the sst.config.ts.

copyFiles[].to?

Type Input<string>

Default The from path in the function package

Destination path relative to function root in the package. By default, it creates the same directory structure as the from path and copies the file.

description?

Type Input<string>

A description for the function. This is displayed in the AWS Console.

{
description: "Handler function for my nightly cron job."
}

dev?

Type Input<false>

Default Live mode enabled in sst dev

Disable running this function Live in sst dev.

{
dev: false
}

environment?

Type Input<Record<string, Input<string>>>

Key-value pairs of values that are set as Lambda environment variables. The keys need to:

  • Start with a letter
  • Be at least 2 characters long
  • Contain only letters, numbers, or underscores

They can be accessed in your function using process.env.<key>.

{
environment: {
DEBUG: "true"
}
}

handler

Type Input<string>

Path to the handler for the function with the format {file}.{method}.

The handler path is relative to the root your repo or the sst.config.ts.

Here there is a file called index.js (or .ts) in the packages/functions/src/ directory with an exported method called handler.

{
handler: "packages/functions/src/index.handler"
}

If bundle is specified, the handler needs to be in the root of the bundle directory.

{
bundle: "packages/functions/src",
handler: "index.handler"
}

layers?

Type Input<Input<string>[]>

A list of Lambda layer ARNs to add to the function.

These are only added when the function is deployed. In sst dev, your functions are run locally, so the layers are not used. Instead you should use a local version of what’s in the layer.

{
layers: ["arn:aws:lambda:us-east-1:123456789012:layer:my-layer:1"]
}

Type Input<any[]>

Link resources to your function. This will:

  1. Grant the permissions needed to access the resources.
  2. Allow you to access it in your function using the SDK.

Takes a list of components to link to the function.

{
link: [bucket, stripeKey]
}

logging?

Type Input<false | Object>

Default {retention: “1 month”, format: “text”}

Configure the function logs in CloudWatch. Or pass in false to disable writing logs.

{
logging: false
}

When set to false, the function is not given permissions to write to CloudWatch. Logs.

logging.format?

Type Input<text | json>

Default “text”

The log format of the Lambda function.

{
logging: {
format: "json"
}
}

logging.logGroup?

Type Input<string>

Default Creates a log group

Assigns the given CloudWatch log group name to the function. This allows you to pass in a previously created log group.

By default, the function creates a new log group when it’s created.

{
logging: {
logGroup: "/existing/log-group"
}
}

logging.retention?

Type Input<1 day | 3 days | 5 days | 1 week | 2 weeks | 1 month | 2 months | 3 months | 4 months | 5 months | 6 months | 1 year | 13 months | 18 months | 2 years | 3 years | 5 years | 6 years | 7 years | 8 years | 9 years | 10 years | forever>

Default 1 month

The duration the function logs are kept in CloudWatch.

Not application when an existing log group is provided.

{
logging: {
retention: "forever"
}
}

memory?

Type Input<${number} MB | ${number} GB>

Default “1024 MB”

The amount of memory allocated for the function. Takes values between 128 MB and 10240 MB in 1 MB increments. The amount of memory affects the amount of virtual CPU available to the function.

{
memory: "10240 MB"
}

name?

Type Input<string>

The name for the function.

By default, the name is generated from the app name, stage name, and component name. This is displayed in the AWS Console for this function.

If you are going to set the name, you need to make sure:

  1. It’s unique across your app.
  2. Uses the app and stage name, so it doesn’t thrash when you deploy to different stages.

Also, changing the name after your’ve deployed it once will create a new function and delete the old one.

{
name: `${$app.name}-${$app.stage}-my-function`
}

nodejs?

Type Input<Object>

Configure how your function is bundled.

By default, SST will bundle your function code using esbuild. This tree shakes your code to only include what’s used; reducing the size of your function package and improving cold starts.

nodejs.banner?

Type Input<string>

Use this to insert a string at the beginning of the generated JS file.

{
nodejs: {
banner: "console.log('Function starting')"
}
}

nodejs.esbuild?

Type Input<BuildOptions>

This allows you to customize esbuild config that is used.

nodejs.format?

Type Input<cjs | esm>

Default “esm”

Configure the format of the generated JS code; ESM or CommonJS.

{
nodejs: {
format: "cjs"
}
}

nodejs.install?

Type Input<string[]>

Dependencies that need to be excluded from the function package.

Certain npm packages cannot be bundled using esbuild. This allows you to exclude them from the bundle. Instead they’ll be moved into a node_modules/ directory in the function package.

This will allow your functions to be able to use these dependencies when deployed. They just won’t be tree shaken. You however still need to have them in your package.json.

Esbuild will ignore them while traversing the imports in your code. So these are the package names as seen in the imports. It also works on packages that are not directly imported by your code.

{
nodejs: {
install: ["pg"]
}
}

nodejs.loader?

Type Input<Record<string, Loader>>

Configure additional esbuild loaders for other file extensions. This is useful when your code is importing non-JS files like .png, .css, etc.

{
nodejs: {
loader: {
".png": "file"
}
}
}

nodejs.minify?

Type Input<boolean>

Default true

Disable if the function code is minified when bundled.

{
nodejs: {
minify: false
}
}

nodejs.plugins?

Type Input<string>

Point to a file that exports a list of esbuild plugins to use.

{
nodejs: {
plugins: "./plugins.mjs"
}
}

The path is relative to the location of the sst.config.ts.

plugins.mjs
import { somePlugin } from "some-plugin";
export default [
somePlugin()
];

You’ll also need to install the npm package of the plugin.

nodejs.sourcemap?

Type Input<boolean>

Default false

Configure if source maps are added to the function bundle when deployed. Since they increase payload size and potentially cold starts, they are not added by default. However, they are always generated during sst dev.

{
nodejs: {
sourcemap: true
}
}

nodejs.splitting?

Type Input<boolean>

Default false

If enabled, modules that are dynamically imported will be bundled in their own files with common dependencies placed in shared chunks. This can help reduce cold starts as your function grows in size.

{
nodejs: {
splitting: true
}
}

permissions?

Type Input<Object[]>

Permissions and the resources that the function needs to access. These permissions are used to create the function’s IAM role.

Allow the function to read and write to an S3 bucket called my-bucket.

{
permissions: [
{
actions: ["s3:GetObject", "s3:PutObject"],
resources: ["arn:aws:s3:::my-bucket/*"]
},
]
}

Allow the function to perform all actions on an S3 bucket called my-bucket.

{
permissions: [
{
actions: ["s3:*"],
resources: ["arn:aws:s3:::my-bucket/*"]
},
]
}

Granting the function permissions to access all resources.

{
permissions: [
{
actions: ["*"],
resources: ["*"]
},
]
}

permissions[].actions

Type string[]

The IAM actions that can be performed.

{
actions: ["s3:*"]
}

permissions[].resources

Type Input<string>[]

The resourcess specified using the IAM ARN format.

{
resources: ["arn:aws:s3:::my-bucket/*"]
}

python?

Type Input<Object>

Configure your python function.

By default, SST will package all files in the same directory as the handler file. This means that you need to your handler file be the root of all files that need to be included in the function package. The only exception to this is a parent pyproject.toml file. SST will look for this file by finding the closest parent directory that contains a pyproject.toml file.

project-root/
├── functions/
│ ├── pyproject.toml
│ ├── handler.py
│ └── utils.py
└── sst.config.ts

python.container?

Type Input<boolean>

Default false

Whether to deploy the function to the container runtime. You should use this if you are deploying a function that needs native dependencies, is large, or if you need to customize some runtime configuration.

{
python: {
container: true
}
}

role?

Type Input<string>

Default Creates a new role

Assigns the given IAM role ARN to the function. This allows you to pass in a previously created role.

By default, the function creates a new IAM role when it’s created. It’ll update this role if you add permissions or link resources.

However, if you pass in a role, you’ll need to update it manually if you add permissions or link resources.

{
role: "arn:aws:iam::123456789012:role/my-role"
}

runtime?

Type Input<nodejs18.x | nodejs20.x | provided.al2023 | python3.9 | python3.10 | python3.11 | python3.12>

Default “nodejs20.x”

The runtime environment for the function. Support for other runtimes is on our roadmap.

{
runtime: "nodejs18.x"
}

storage?

Type Input<${number} MB | ${number} GB>

Default “512 MB”

The amount of ephemeral storage allocated for the function. This sets the ephemeral storage of the lambda function (/tmp). Must be between “512 MB” and “10240 MB” (“10 GB”) in 1 MB increments.

{
storage: "5 GB"
}

streaming?

Type Input<boolean>

Default false

Enable streaming for the function.

Streaming is only supported when using the function url is enabled and not when using it with API Gateway.

You’ll also need to wrap your handler with awslambda.streamifyResponse to enable streaming.

While sst dev doesn’t support streaming, you can use the lambda-stream package to test locally.

Check out the AWS Lambda streaming example for more details.

{
streaming: true
}

tags?

Type Input<Record<string, Input<string>>>

A list of tags to add to the function.

{
tags: {
"my-tag": "my-value"
}
}

timeout?

Type Input<${number} minute | ${number} minutes | ${number} second | ${number} seconds>

Default “20 seconds”

The maximum amount of time the function can run. The minimum timeout is 1 second and the maximum is 900 seconds or 15 minutes.

While the maximum timeout is 15 minutes, if a function is connected to other services, it’ll time out based on those limits. API Gateway for example has a timeout of 30 seconds. So even if the function has a timeout of 15 minutes, the API request will time out after 30 seconds.

{
timeout: "900 seconds"
}

transform?

Type Object

Transform how this component creates its underlying resources.

transform.function?

Type FunctionArgs | (args: FunctionArgs, opts: ComponentResourceOptions, name: string) => void

Transform the Lambda Function resource.

transform.logGroup?

Type LogGroupArgs | (args: LogGroupArgs, opts: ComponentResourceOptions, name: string) => void

Transform the CloudWatch LogGroup resource.

transform.role?

Type RoleArgs | (args: RoleArgs, opts: ComponentResourceOptions, name: string) => void

Transform the IAM Role resource.

url?

Type Input<boolean | Object>

Default false

Enable Lambda function URLs. These are dedicated endpoints for your Lambda functions.

Enable it with the default options.

{
url: true
}

Configure the authorization and CORS settings for the endpoint.

{
url: {
authorization: "iam",
cors: {
allowOrigins: ['https://example.com']
}
}
}

url.authorization?

Type Input<none | iam>

Default “none”

The authorization used for the function URL. Supports IAM authorization.

{
url: {
authorization: "iam"
}
}

url.cors?

Type Input<boolean | Object>

Default true

Customize the CORS (Cross-origin resource sharing) settings for the function URL.

Disable CORS.

{
url: {
cors: false
}
}

Only enable the GET and POST methods for https://example.com.

{
url: {
cors: {
allowMethods: ["GET", "POST"],
allowOrigins: ["https://example.com"]
}
}
}
url.cors.allowCredentials?

Type Input<boolean>

Default false

Allow cookies or other credentials in requests to the function URL.

{
url: {
cors: {
allowCredentials: true
}
}
}
url.cors.allowHeaders?

Type Input<Input<string>[]>

Default [”*”]

The HTTP headers that origins can include in requests to the function URL.

{
url: {
cors: {
allowHeaders: ["date", "keep-alive", "x-custom-header"]
}
}
}
url.cors.allowMethods?

Type Input<Input<GET | POST | PUT | DELETE | HEAD | OPTIONS | PATCH | *>[]>

Default [”*”]

The HTTP methods that are allowed when calling the function URL.

{
url: {
cors: {
allowMethods: ["GET", "POST", "DELETE"]
}
}
}

Or the wildcard for all methods.

{
url: {
cors: {
allowMethods: ["*"]
}
}
}
url.cors.allowOrigins?

Type Input<Input<string>[]>

Default [”*”]

The origins that can access the function URL.

{
url: {
cors: {
allowOrigins: ["https://www.example.com", "http://localhost:60905"]
}
}
}

Or the wildcard for all origins.

{
url: {
cors: {
allowOrigins: ["*"]
}
}
}
url.cors.exposeHeaders?

Type Input<Input<string>[]>

Default []

The HTTP headers you want to expose in your function to an origin that calls the function URL.

{
url: {
cors: {
exposeHeaders: ["date", "keep-alive", "x-custom-header"]
}
}
}
url.cors.maxAge?

Type Input<${number} minute | ${number} minutes | ${number} hour | ${number} hours | ${number} second | ${number} seconds | ${number} day | ${number} days>

Default “0 seconds”

The maximum amount of time the browser can cache results of a preflight request. By default the browser doesn’t cache the results. The maximum value is 86400 seconds or 1 day.

{
url: {
cors: {
maxAge: "1 day"
}
}
}

versioning?

Type Input<boolean>

Default false

Enable versioning for the function.

{
versioning: true
}

volume?

Type Input<Object>

Mount an EFS file system to the function.

Create an EFS file system.

sst.config.ts
const vpc = new sst.aws.Vpc("MyVpc");
const fileSystem = new sst.aws.Efs("MyFileSystem", { vpc });

And pass it in.

{
volume: {
efs: fileSystem
}
}

By default, the file system will be mounted to /mnt/efs. You can change this by passing in the path property.

{
volume: {
efs: fileSystem,
path: "/mnt/my-files"
}
}

To use an existing EFS, you can pass in an EFS access point ARN.

{
volume: {
efs: "arn:aws:elasticfilesystem:us-east-1:123456789012:access-point/fsap-12345678",
}
}

volume.efs

Type Input<string | Efs>

The EFS file system to mount. Or an EFS access point ARN.

volume.path?

Type Input<string>

Default “/mnt/efs”

The path to mount the volume.

vpc?

Type Input<Vpc | Object>

Configure the function to connect to private subnets in a virtual private cloud or VPC. This allows your function to access private resources.

{
vpc: {
privateSubnets: ["subnet-0b6a2b73896dc8c4c", "subnet-021389ebee680c2f0"]
securityGroups: ["sg-0399348378a4c256c"],
}
}

vpc.privateSubnets

Type Input<Input<string>[]>

A list of VPC subnet IDs.

vpc.securityGroups

Type Input<Input<string>[]>

A list of VPC security group IDs.

vpc.subnets?

Type Input<Input<string>[]>

A list of VPC subnet IDs.

Properties

arn

Type Output<string>

The ARN of the Lambda function.

name

Type Output<string>

The name of the Lambda function.

nodes

Type Object

The underlying resources this component creates.

nodes.function

Type Output<Function>

The AWS Lambda function.

nodes.logGroup

Type Output<undefined | LogGroup>

The CloudWatch Log Group the function logs are stored.

nodes.role

Type Role

The IAM Role the function will use.

url

Type Output<string>

The Lambda function URL if url is enabled.

SDK

Use the SDK in your runtime to interact with your infrastructure.


This is accessible through the Resource object in the SDK.

  • name string

    The name of the Lambda function.

  • url undefined | string

    The Lambda function URL if url is enabled.