Examples
A collection of example apps for reference.
Below are a collection of example SST apps. These are available in the examples/
directory of the repo.
The descriptions for these examples are generated using the comments in the sst.config.ts
of the app.
Contributing
To contribute an example or to edit one, submit a PR to the repo.
Make sure to document the sst.config.ts
in your example.
API Gateway auth
Enable IAM and JWT authorizers for API Gateway routes.
View the full example.
Bucket policy
Create an S3 bucket and transform its bucket policy.
View the full example.
Bucket queue notifications
Create an S3 bucket and subscribe to its events with an SQS queue.
View the full example.
Bucket notifications
Create an S3 bucket and subscribe to its events with a function.
View the full example.
Bucket topic notifications
Create an S3 bucket and subscribe to its events with an SNS topic.
View the full example.
Subscribe to queues
Create an SQS queue, subscribe to it, and publish to it from a function.
View the full example.
DynamoDB streams
Create a DynamoDB table, enable streams, and subscribe to it with a function.
View the full example.
FFmpeg in Lambda
Uses FFmpeg to process videos. In this example, it takes a clip.mp4
and grabs a single frame from it.
We use the ffmpeg-static
package that
contains pre-built binaries for all architectures.
We can use this to spawn a child process and run FFmpeg.
We don’t need a layer when we deploy this because SST will use the right binary for the
target Lambda architecture; including arm64
.
All this is handled by nodejs.install
.
View the full example.
IAM permissions boundaries
Use permissions boundaries to set the maximum permissions for all IAM roles that’ll be created in your app.
In this example, the Function has the s3:ListAllMyBuckets
and sqs:ListQueues
permissions. However, we create a permissions boundary that only allows s3:ListAllMyBuckets
.
And we apply it to all Roles in the app using the global
$transform
.
As a result, the Function is only allowed to list S3 buckets. If you open the deployed URL, you’ll see that the SQS list call fails.
Learn more about AWS IAM permissions boundaries.
View the full example.
Current AWS account
You can use the aws.getXXXXOutput()
provider functions to get info about the current
AWS account.
Learn more about provider functions.
View the full example.
Kinesis streams
Create a Kinesis stream, and subscribe to it with a function.
View the full example.
AWS multi-region
To deploy resources to multiple AWS regions, you can create a new provider for the region you want to deploy to.
And then pass that in to the resource.
If no provider is passed in, the default provider will be used. And if no region is specified, the default region from your credentials will be used.
View the full example.
AWS Next.js basic auth
Deploys a simple Next.js app and adds basic auth to it.
This is useful for dev environments where you want to share your app your team but ensure that it’s not publicly accessible.
This works by injecting some code into a CloudFront function that checks the basic auth
header and matches it against the USERNAME
and PASSWORD
secrets.
To deploy this, you need to first set the USERNAME
and PASSWORD
secrets.
If you are deploying this to preview environments, you might want to set the secrets using
the --fallback
flag.
View the full example.
Prisma in Lambda
To use Prisma in a Lambda function you need to
- Generate the Prisma Client with the right architecture
- Copy the generated client to the function
- Run the function inside a VPC
You can set the architecture using the binaryTargets
option in prisma/schema.prisma
.
You can also switch to ARM, just make sure to also change the function architecture in your
sst.config.ts
.
To generate the client, you need to run prisma generate
when you make changes to the
schema.
Since this needs to be done on every deploy, we add a postinstall
script to the package.json
.
This runs the command on npm install
.
We then need to copy the generated client to the function when we deploy.
Our function also needs to run inside a VPC, since Prisma doesn’t support the Data API.
Prisma in serverless environments
Prisma is not great in serverless environments. For a couple of reasons:
- It doesn’t support Data API, so you need to manage the connection pool on your own.
- Without the Data API, your functions need to run inside a VPC.
- You cannot use
sst dev
without connecting to the VPC.
- You cannot use
- Due to the internal architecture of their client, it’s also has slower cold starts.
Instead we recommend using Drizzle. This example is here for reference for people that are already using Prisma.
View the full example.
Puppeteer in Lambda
To use Puppeteer in a Lambda function you need:
puppeteer-core
- Chromium
- In
sst dev
, we’ll use a locally installed Chromium version. - In
sst deploy
, we’ll use the@sparticuz/chromium
package. It comes with a pre-built binary for Lambda.
- In
Chromium version
Since Puppeteer has a preferred version of Chromium, we’ll need to check the version of Chrome that a given version of Puppeteer supports. Head over to the Puppeteer’s Chromium Support page and check which versions work together.
For example, Puppeteer v23.1.1 supports Chrome for Testing 127.0.6533.119. So, we’ll use the
v127 of @sparticuz/chromium
.
Install Chromium locally
To use this locally, you’ll need to install Chromium.
Once installed you’ll see the location of the Chromium binary, /tmp/localChromium/chromium/mac_arm-1350406/chrome-mac/Chromium.app/Contents/MacOS/Chromium
.
Update this in your Lambda function.
You’ll notice we are using the right binary with the SST_DEV
environment variable.
Deploy
We don’t need a layer to deploy this because @sparticuz/chromium
comes with a pre-built
binary for Lambda.
We just need to set it in the nodejs.install
.
And on deploy, SST will use the right binary.
We are giving our function more memory and a longer timeout since running Puppeteer can take a while.
View the full example.
Subscribe to queues
Create an SQS queue, subscribe to it, and publish to it from a function.
View the full example.
AWS Router and bucket
Creates a router that serves static files from the public
folder in a bucket.
View the full example.
Router and function URL
Creates a router that routes all requests to a function with a URL.
View the full example.
Sharp in Lambda
Uses the Sharp library to resize images. In this example,
it resizes a logo.png
local file to 100x100 pixels.
We don’t need a layer to deploy this because sharp
comes with a pre-built binary for Lambda.
This is handled by nodejs.install
.
In dev, this uses the sharp npm package locally.
On deploy, SST will use the right binary from the sharp package for the target Lambda architecture.
View the full example.
AWS static site basic auth
This deploys a simple static site and adds basic auth to it.
This is useful for dev environments where you want to share a static site with your team but ensure that it’s not publicly accessible.
This works by injecting some code into a CloudFront function that checks the basic auth
header and matches it against the USERNAME
and PASSWORD
secrets.
To deploy this, you need to first set the USERNAME
and PASSWORD
secrets.
If you are deploying this to preview environments, you might want to set the secrets using
the --fallback
flag.
View the full example.
AWS static site
Deploy a simple HTML file as a static site with S3 and CloudFront. The website is stored in
the site/
directory.
View the full example.
Swift in Lambda
Deploys a simple Swift application to Lambda using the al2023
runtime.
Check out the README in the repo for more details.
View the full example.
T3 Stack in AWS
Deploy T3 stack with Drizzle and Postgres to AWS. To use this example run:
And deploy it to production with.
This example was created using create-t3-app
and the following options: tRPC, Drizzle,
no auth, Tailwind, Postgres, and the App Router
Instead of a local database, we’ll be using an RDS Postgres database and connect to it with the RDS Data API.
In our Next.js app we can access our Postgres database because we link them
both. We don’t need to use our .env
files.
For Drizzle Kit, we use the aws-data-api
driver.
And to make sure our credentials are available, we update our package.json
with the sst shell
CLI.
So running npm run db:push
will run Drizzle Kit with the right credentials.
View the full example.
Subscribe to topics
Create an SNS topic, publish to it from a function, and subscribe to it with a function and a queue.
View the full example.
Vector search
Store and search for vector data using the Vector component. Includes a seeder API that uses an LLM to generate embeddings for some movies and optionally their posters.
Once seeded, you can call the search API to query the vector database.
View the full example.
React SPA with Vite
Deploy a React single-page app (SPA) with Vite to S3 and CloudFront.
View the full example.
Cloudflare KV
This example creates a Cloudflare KV namespace and links it to a worker. Now you can use the SDK to interact with the KV namespace in your worker.
View the full example.
Link multiple secrets
You might have multiple secrets that need to be used across your app. It can be tedious to create a new secret and link it to each function or resource.
A common pattern to addresses this is to create an object with all your secrets and then link them all at once. Now when you have a new secret, you can add it to the object and it will be automatically available to all your resources.
View the full example.
Default function props
Set default props for all the functions in your app using the global $transform
.
View the full example.
Vercel domains
Creates a router that uses domains purchased through and hosted in your Vercel account.
Ensure the VERCEL_API_TOKEN
and VERCEL_TEAM_ID
environment variables are set.
View the full example.