Skip to main content
Components are the building blocks of your SST application. They represent cloud resources like functions, databases, APIs, and more.

What are components?

Components are TypeScript classes that create and manage cloud resources. SST provides high-level components for common use cases, and you can also use low-level Pulumi resources when needed.
sst.config.ts
const bucket = new sst.aws.Bucket("MyBucket");
const fn = new sst.aws.Function("MyFunction", {
  handler: "src/lambda.handler",
});
Each component:
  • Has a unique name within your app
  • Takes configuration props specific to that resource type
  • Creates the necessary cloud resources automatically
  • Can be linked to other components

Built-in components

SST provides components for both AWS and Cloudflare. Here are some commonly used ones:

Compute

Function

AWS Lambda functions with live development

Service

Long-running containers on ECS

Worker

Cloudflare Workers

Cron

Scheduled tasks

APIs

ApiGatewayV2

HTTP APIs with API Gateway

AppSync

GraphQL APIs

Realtime

WebSocket connections with pub/sub

Frontends

Nextjs

Next.js applications

Remix

Remix applications

Astro

Astro sites

StaticSite

Static websites

Storage

Bucket

S3 buckets for object storage

Dynamo

DynamoDB tables

Postgres

RDS Postgres databases

Redis

ElastiCache Redis clusters

Queues & Events

Queue

SQS queues with Lambda subscribers

SnsTopic

SNS topics for pub/sub

Bus

EventBridge event buses

Component structure

Every component follows this pattern:
const resource = new sst.aws.ComponentName("LogicalName", {
  // Configuration props
  prop1: "value1",
  prop2: "value2",
});
  • Logical name — A unique identifier within your app (e.g., "MyBucket")
  • Props — Configuration options specific to the component

Logical names

The logical name is how you reference the component in your code and in the SST Console. It must be unique within your app.
const userBucket = new sst.aws.Bucket("UserBucket");
const assetBucket = new sst.aws.Bucket("AssetBucket");
Changing a component’s logical name will cause SST to delete the old resource and create a new one. Make sure to use consistent names.

Physical names

SST automatically generates physical names for your resources by prefixing them with your app name and stage:
# Logical name: "MyBucket"
# Physical name: "my-app-dev-mybucket-a1b2c3d4"
This ensures:
  • Resources don’t conflict across stages
  • Resources are identifiable in the AWS Console
  • Names comply with AWS naming restrictions

Using components

Define components in the run function of your sst.config.ts:
sst.config.ts
/// <reference path="./.sst/platform/config.d.ts" />

export default $config({
  app(input) {
    return {
      name: "my-app",
      home: "aws",
    };
  },
  async run() {
    // Create an S3 bucket
    const bucket = new sst.aws.Bucket("MyBucket", {
      public: true,
    });

    // Create a Lambda function
    const api = new sst.aws.Function("MyApi", {
      handler: "src/api.handler",
      link: [bucket],
      url: true,
    });

    return { api: api.url };
  },
});

Accessing properties

Component properties are Pulumi Outputs, which means they’re computed during deployment:
const bucket = new sst.aws.Bucket("MyBucket");

// Access the bucket name (this is an Output<string>)
const bucketName = bucket.name;

// Use .apply() to access the actual value
bucketName.apply(name => {
  console.log("Bucket name:", name);
});
Outputs ensure that dependencies between resources are tracked correctly during deployment.

Subscribing to events

Many components support subscribing to events:
const bucket = new sst.aws.Bucket("MyBucket");

// Subscribe to object creation events
bucket.subscribe("src/subscriber.handler", {
  events: ["s3:ObjectCreated:*"],
});
const queue = new sst.aws.Queue("MyQueue");

// Subscribe with a function
queue.subscribe("src/worker.handler");

Using Pulumi resources

You can use any Pulumi resource alongside SST components:
import * as aws from "@pulumi/aws";

// SST component
const bucket = new sst.aws.Bucket("MyBucket");

// Pulumi resource
const table = new aws.dynamodb.Table("MyTable", {
  attributes: [
    { name: "id", type: "S" },
  ],
  hashKey: "id",
  billingMode: "PAY_PER_REQUEST",
});
SST components are built on top of Pulumi, so they work seamlessly together.

Component transforms

You can use transforms to modify how components are created:
sst.config.ts
// Apply tags to all Lambda functions
$transform(sst.aws.Function, (args) => {
  args.tags = {
    ...args.tags,
    team: "backend",
  };
});

const fn = new sst.aws.Function("MyFunction", {
  handler: "src/lambda.handler",
  // Will automatically have team: "backend" tag
});
Transforms let you:
  • Enforce organizational standards
  • Apply consistent configurations
  • Modify default behaviors

Dev mode behavior

Some components behave differently in sst dev:
  • Functions — Run locally with Live Lambda Development
  • Frontends — Start their dev server instead of deploying
  • Services — Run their dev command instead of deploying to ECS
  • Databases — Can connect to local instances (Postgres, Redis)
You can customize dev mode behavior with the dev prop:
const site = new sst.aws.Nextjs("MySite", {
  dev: {
    command: "npm run dev",
    directory: "packages/web",
  },
});

Best practices

Use meaningful names

Give components descriptive logical names:
// Good
const userTable = new sst.aws.Dynamo("UserTable");
const uploadBucket = new sst.aws.Bucket("UploadBucket");

// Avoid
const table1 = new sst.aws.Dynamo("Table1");
const bucket = new sst.aws.Bucket("Bucket");
Organize related components together:
// Auth resources
const userPool = new sst.aws.CognitoUserPool("UserPool");
const userTable = new sst.aws.Dynamo("UserTable");

// Storage resources
const uploadBucket = new sst.aws.Bucket("UploadBucket");
const assetBucket = new sst.aws.Bucket("AssetBucket");

Use linking

Prefer linking over manual permissions:
// Good - automatic permissions
const fn = new sst.aws.Function("MyFunction", {
  handler: "src/handler.handler",
  link: [bucket],
});

// Avoid - manual permissions
const fn = new sst.aws.Function("MyFunction", {
  handler: "src/handler.handler",
  permissions: [{
    actions: ["s3:*"],
    resources: [bucket.arn],
  }],
});

Next steps

Linking

Connect components together

Config

Learn about sst.config.ts

Component Reference

Browse all components

Providers

Add cloud providers

Build docs developers (and LLMs) love