Upgrade Guide
Upgrade guide for all notable SST releases.
To view the latest release and all historical releases, head over to our GitHub release page.
Upgrade to v2.38.0
Service
now requires port
to be set. If previously unset, set the port
to 3000.
new Service(stack, "Site", {
+ port: 3000,
});
Upgrade to v2.36.0
NextjsSite
now sends logs for individual routes to separate log groups. To continue using a single log group, set logging
to combined
.
new NextjsSite(stack, "Site", {
+ logging: "combined",
});
Upgrade to v2.35.0
The default runtime for functions has been updated from nodejs16.x
to nodejs18.x
in response to AWS Lambda's deprecation announcement for the Node.js 16 runtime. To continue using Node.js 16, specify nodejs16.x
as the default runtime
.
app.setDefaultFunctionProps({
+ runtime: "nodejs16.x",
});.
Upgrade to v2.34.0
AstroSite
now infers the edge
mode from the astro-sst
adapter. Remove the edge
prop from AstroSite
.
new AstroSite(stack, "Site", {
- edge: true,
});
And set the deployment strategy to edge
in astro.config.js
- import aws from "astro-sst/edge";
+ import aws from "astro-sst";
export default defineConfig({
output: "server",
adapter: aws({
+ deploymentStrategy: "edge",
}),
});
Upgrade to v2.32.0
NextjsSite
, AstroSite
, RemixSite
, SvelteKitSite
, SolidStartSite
, and StaticSite
now support enhanced cache invalidation options with the invalidation
prop. Replace waitForInvalidation
with invalidation.wait
, as waitForInvalidation
is deprecated.
new NextjsSite(stack, "Site", {
- waitForInvalidation: true,
+ invalidation: {
+ wait: true,
+ },
});
Upgrade to v2.31.0
NextjsSite
, AstroSite
, RemixSite
, SvelteKitSite
, SolidStartSite
, and StaticSite
now support enhanced file options with the assets
prop. Replace fileOptions
with assets.fileOptions
, as fileOptions
is deprecated.
new NextjsSite(stack, "Site", {
- fileOptions: [
- {
- exclude: "*",
- include: "*.zip",
- cacheControl: "public,max-age=31536000,immutable",
- },
- ],
+ assets: {
+ fileOptions: [
+ {
+ files: "**/*.zip",
+ cacheControl: "public,max-age=31536000,immutable",
+ },
+ ],
+ },
});
Upgrade to v2.27.0
AstroSite has been re-architectured to support deploying Astro sites in a "hybrid" mode, coupled with other SSR improvements. sites should operate seamlessly, as the update is largely backward compatible. However, if your Astro app contains non-GET routes, such us form submissions, logins, or API endpoints, you'll need to specify them manually:
new AstroSite(stack, "Site", {
path: "my-astro-app/",
+ regional: {
+ serverRoutes: [
+ "feedback", // Feedback page which requires POST method
+ "login", // Login page which requires POST method
+ "user/*", // Directory of user routes which are all SSR
+ "api/*" // Directory of API endpoints which require all methods
+ ]
+ }
});
Upgrade to v2.3.0
Resource Binding now lets you bind resources to your frontend frameworks. It simplifies accessing the resources in the server side rendered (SSR) code. For example, here's how we bind the bucket to the Next.js app:
const bucket = new Bucket(stack, "myFiles");
new NextjsSite(stack, "mySite", {
- environment: {
- BUCKET_NAME: bucket.bucketName,
- },
- permissions: [bucket],
+ bind: [bucket],
});
And here's how we access it in our SSR code.
+ import { Bucket } from "sst/node/bucket";
- process.env.BUCKET_NAME
+ Bucket.myFiles.bucketName
Following are the steps to upgrade.
sst env
has been renamed tosst bind
(although both will work).sst env
will be removed in SST v3- sst env next dev
+ sst bind next dev
Upgrade to v2.0
The 2.0 upgrade is primarily ergonomic and should not result in any infrastructure changes.
Packages
SST is now a monorepo, remove all packages referencing
@serverless-stack/resources
@serverless-stack/cli
@serverless-stack/node
and@serverless-stack/static-site-env
. Install thesst
package{
"devDependencies": {
- "@serverless-stack/resources": "xxx",
- "@serverless-stack/cli": "xxx",
- "@serverless-stack/static-site-env": "xxx",
- "@serverless-stack/node": "xxx",
+ "sst": "2.x",
+ "constructs": "10.1.156"
}
}Ensure
"constructs": "10.1.156"
is installedIn your stacks code replace all imports from
@serverless-stack/resources
tosst/constructs
- import { Function } from "@serverless-stack/resources"
+ import { Function } from "sst/constructs"If you were using
@serverless-stack/static-site-env
for your frontend, replace it with thesst env '<command>'
command"scripts": {
- "dev": "static-site-env -- vite dev",
+ "dev": "sst env vite dev",
}
App configuration
sst.json
is now specified as a sst.config.ts
file. The main
field has been replaced with a function that can directly import your stacks.
import type { SSTConfig } from "sst"
import { Api } from "./stacks/Api.js"
import { Dynamo } from "./stacks/Dynamo.js"
export default {
config(input) {
return {
name: "myapp",
region: "us-east-1",
profile: "my-company-dev"
}
},
stacks(app) {
app.setDefaultFunctionProps({
runtime: "nodejs18.x",
architecture: "arm_64",
})
app
.stack(Api)
.stack(Dynamo)
},
} satisfies SSTConfig
CLI
sst start
has been renamed tosst dev
(although both will work)sst load-config
has been removed — see v1.16sst dev
requires additional IAM permissions:- iot:Connect
- iot:DescribeEndpoint
- iot:Publish
- iot:Receive
- iot:Subscribe
View the complete list of permissions required by the CLI.
Stacks code
In stacks code, process.env.IS_LOCAL is no longer available. Please use app.mode to see if it's running in "dev" mode.
app.local
will continue to work but likely will be deprecated at some point.SST no longer requires a DebugStack to be deployed - feel free to delete this from your AWS console.
Function
- Default runtime is
nodejs16.x
- Default format is
esm
instead ofcjs
. However, you might have some dependencies that have not properly supportedesm
yet. To get around this you can set theformat
tocjs
in your default function props. While v2 doesn't need you to upgrade toesm
, the SST Node client requiresesm
because of their use of top-level await. So it's recommended that you move over in the near future.sst.config.tsapp.setDefaultFunctionProps({
nodejs: {
format: "cjs",
},
}); - We've made changes to the
FunctionProps
API so you should be seeing type errors around thebundle
property. Most of the options there have been moved to anodejs
property instead.const fn = new Function(stack, "fn", {
- bundle: {
- format: "esm",
- },
+ nodejs: {
+ format: "esm"
+ }
}) - We've removed the need for
srcPath
in function definitions but all your handler paths need to be specified relative to the root of the project.new Function(stack, "fn", {
- srcPath: "services",
- handler: "path/to/func.handler"
+ handler: "services/path/to/func.handler"
}) - Removed
config
prop — see v1.16
- Default runtime is
Api: removed the
pothos
route type — see v1.18StaticSite, NextjsSite, and RemixSite
- Following attributes were renamed:
bucketArn
renamed tocdk.bucket.bucketArn
bucketName
renamed tocdk.bucket.bucketName
distributionId
renamed tocdk.distribution.distributionId
distributionDomain
renamed tocdk.distribution.distributionDomainName
const site = new StaticSite(stack, "MySite");
- site.bucketArn
- site.bucketName
- site.distributionId
- site.distributionDomain
+ site.cdk.bucket.bucketArn
+ site.cdk.bucket.bucketName
+ site.cdk.distribution.distributionId
+ site.cdk.distribution.distributionDomainName - Running
sst dev
no longer deploys a placeholder sitesite.url
isundefined
in dev modesite.customDomainUrl
isundefined
in dev mode
waitForInvalidation
now defaults tofalse
- Following attributes were renamed:
NextjsSite
- in SST v1, the
NextjsSite
construct uses the@sls-next/lambda-at-edge package
package from theserverless-next.js
project to build and package your Next.js app so that it can be deployed to AWS. The project is no longer maintained. SST v2 uses theOpenNext
project. You can still use the oldNextjsSite
construct like this:import { NextjsSite } from "sst/constructs/deprecated";
commandHooks.afterBuild
renamed tobuildCommand
new NextjsSite(stack, "NextSite", {
path: "path/to/site",
- commandHooks: {
- afterBuild: ["npx next-sitemap"],
- }
+ buildCommand: "npx open-next@latest build && npx next-sitemap"
});
- in SST v1, the
Removed ViteStaticSite and ReactStaticSite — see v1.18
Removed GraphQLApi — see v1.18
Function code
- In your functions code replace all imports from
@serverless-stack/node/xxx
tosst/node/xxx
- import { Bucket } from "@serverless-stack/node/bucket"
+ import { Bucket } from "sst/node/bucket" - If you're using function binding we moved type generation into a
.sst
folder. To include this place ansst-env.d.ts
file in any package that needs the types that contains the following:Make sure you specify the path correctly/// <reference path="../.sst/types/index.ts" />
Secrets
- The SSM parameter path for storing the secret values have changed in v1.16. If you are upgrading from a version prior to v1.16, run this
sst transform
command in each stage with secrets set:sst transform resource-binding-secrets
Say bye to debug stack 👋
In v1, SST used to deploy a debug stack in your AWS account when you ran sst start
. Debug stack contains resources required for Live Lambda Development to work. In v2, SST no longer need the debug stack. You can remove it by going to your AWS CloudFormation console. Find the stack named {stageName}-{appName}-debug-stack
, where {stageName}
is the name of the stage, and {appName}
is the name of your SST app. And remove the stack.
Upgrade to v1.18
Constructs
Api: The
pothos
route type is renamed tographql
, and will be removed in SST v2.new Api(stack, "api", {
routes: {
"POST /graphql": {
- type: "pothos",
+ type: "graphql",
function: handler: "functions/graphql/graphql.ts",
- schema: "backend/functions/graphql/schema.ts",
- output: "graphql/schema.graphql",
- commands: [
- "./genql graphql/graphql.schema graphql/
- ]
+ pothos: {
+ schema: "backend/functions/graphql/schema.ts",
+ output: "graphql/schema.graphql",
+ commands: [
+ "./genql graphql/graphql.schema graphql/
+ ]
+ }
}
}
});GraphQLApi: The
GraphQLApi
construct is deprecated, and will be removed in SST v2. Use theApi
construct with agraphql
route instead.- new GraphQLApi(stack, "api", {
- server: "src/graphql.handler",
- });
+ new Api(stack, "api", {
+ routes: {
+ "POST /": {
+ type: "graphql",
+ function: "src/graphql.handler",
+ }
+ }
+ });Note that the
GraphQLApi
construct used to create bothGET
andPOST
routes. In most cases, onlyPOST
is used. You can also create theGET
route like this:new Api(stack, "api", {
routes: {
+ "GET /": {
+ type: "graphql",
+ function: "src/graphql.handler",
+ },
"POST /": {
type: "graphql",
function: "src/graphql.handler",
}
}
});ViteStaticSite: The
ViteStaticSite
construct is deprecated, and will be removed in SST v2. Use theStaticSite
construct instead. SpecifybuildCommand
,buildOutput
, and renametypesPath
tovite.types
.- new ViteStaticSite(stack, "frontend", {
+ new StaticSite(stack, "frontend", {
path: "path/to/src",
+ buildCommand: "npm run build", // or "yarn build"
+ buildOutput: "dist",
customDomain: "mydomain.com",
environment: {
VITE_API_URL: api.url,
},
- typesPath: "types/my-env.d.ts",
+ vite: {
+ types: "types/my-env.d.ts",
+ }
});ReactStaticSite: The
ReactStaticSite
construct is deprecated, and will be removed in SST v2. Use theStaticSite
construct instead. SpecifybuildCommand
andbuildOutput
.- new ReactStaticSite(stack, "frontend", {
+ new StaticSite(stack, "frontend", {
path: "path/to/src",
+ buildCommand: "npm run build", // or "yarn build"
+ buildOutput: "build",
customDomain: "mydomain.com",
environment: {
REACT_APP_API_URL: api.url,
},
});
Upgrade to v1.16
Resource Binding was introduced in this release. It simplifies accessing the resources in your app. For example, here's how we bind the bucket to the function:
const bucket = new Bucket(stack, "myFiles");
new Function(stack, "myFunction", {
handler: "lambda.handler",
- environment: {
- BUCKET_NAME: bucket.bucketName,
- },
- permissions: [bucket],
+ bind: [bucket],
});
And here's how we access it in our function.
+ import { Bucket } from "@serverless-stack/node/bucket";
- process.env.BUCKET_NAME
+ Bucket.myFiles.bucketName
Following are the steps to upgrade.
CLI
The path for the SSM parameters that stores the secrets has changed. So you'll need to run
sst deploy
orsst dev
before using thesst secrets
CLI.The
sst load-config
command is being renamed tosst bind
and will be removed in SST v2- sst load-config -- vitest run
+ sst bind -- vitest run
Constructs
Construct IDs need to be unique and match the pattern
[a-zA-Z]([a-zA-Z0-9-_])+
. If you have constructs with clashing IDs, change to a unique ID. And pass the old ID intocdk.id
to ensure CloudFormation does not recreate the resource.For example, if you have two buckets with the same id.
- new Bucket(stack, "bucket");
- new Bucket(stack, "bucket");
+ new Bucket(stack, "usersFiles", {
+ cdk: { id: "bucket" },
+ });
+ new Bucket(stack, "adminFiles", {
+ cdk: { id: "bucket" },
+ });Function/Job: Pass Secrets and Parameters into
bind
instead ofconfig
. Theconfig
option will be removed in SST v2.new Function(stack, "myFn", {
- config: [MY_STRIPE_KEY],
+ bind: [MY_STRIPE_KEY],
});
new Job(stack, "myJob", {
- config: [MY_STRIPE_KEY],
+ bind: [MY_STRIPE_KEY],
});Function/Job: Pass SST Constructs into
bind
instead ofpermissions
to grant permissions.permissions
will not accept SST Constructs in SST v2.new Function(stack, "myFn", {
- permissions: [myTopic],
+ bind: [myTopic],
});
new Job(stack, "myJob", {
- permissions: [myTopic],
+ bind: [myTopic],
});App/Stack: Pass Secrets and Parameters into
addDefaultFunctionBinding
instead ofaddDefaultFunctionConfig
.addDefaultFunctionConfig
will be removed in SST v2- app.addDefaultFunctionConfig([MY_STRIPE_KEY]);
+ app.addDefaultFunctionBinding([MY_STRIPE_KEY]);
- stack.addDefaultFunctionConfig([MY_STRIPE_KEY]);
+ stack.addDefaultFunctionBinding([MY_STRIPE_KEY]);App/Stack: Pass SST Constructs into
addDefaultFunctionBinding
instead ofaddDefaultFunctionPermissions
to grant permissions.addDefaultFunctionPermissions
will not accept SST Constructs in SST v2.- app.addDefaultFunctionPermissions([myTopic]);
+ app.addDefaultFunctionBinding([myTopic]);
- stack.addDefaultFunctionPermissions([myTopic]);
+ stack.addDefaultFunctionBinding([myTopic]);
Client
Change
Job.run("myJob")
toJob.myJob.run()
in your functions code.- Job.run("myJob", { payload });
+ Job.myJob.run({ payload });
Upgrade to v1.10
Constructs
The old
Auth
construct has been renamed toCognito
construct.- new Auth(stack, "auth", {
+ new Cognito(stack, "auth", {
login: ["email"],
});
Upgrade to v1.3
Constructs
Auth:
attachPermissionsForAuthUsers()
andattachPermissionsForUnauthUsers()
now take a scope as the first argument.const auth = new Auth(stack, "auth", {
login: ["email"],
});
- auth.attachPermissionsForAuthUsers(["s3", "sns"]);
+ auth.attachPermissionsForAuthUsers(auth, ["s3", "sns"]);
- auth.attachPermissionsForUnauthUsers(["s3"]);
+ auth.attachPermissionsForUnauthUsers([auth, "s3"]);