Is Vercel’s premium markup draining your startup's runway, or is AWS CDK’s verbose boilerplate driving your engineering team to the brink of burnout? In the search for the best serverless IaC 2026 has to offer, developers face a critical architectural fork in the road: stick with AWS’s native heavyweight or jump to the highly optimized, Pulumi-driven SST Ion. This comprehensive SST v3 vs AWS CDK comparison will dissect the architectural shifts, developer experiences, state management, and security patterns of both tools to help you decide which is the right foundation for your next-generation cloud stack.
The Architectural Paradigm Shift: CDK vs. SST Ion
To understand the SST v3 vs AWS CDK debate, we must first look at how their underlying engines have diverged. AWS CDK has remained a template-driven framework. You write TypeScript, Python, or Java code, which the CDK synthesizes into massive, declarative CloudFormation templates. AWS then ingests these templates, executing the deployments transactionally in the cloud.
Conversely, SST v3 (codenamed SST Ion) represents a complete architectural departure. In its previous iteration (v2), SST was built directly on top of AWS CDK. However, to solve the chronic deployment bottlenecks of CloudFormation, the SST team rebuilt v3 on top of the SST Pulumi engine, utilizing Terraform providers underneath.
This shift from CloudFormation to an API-driven model means SST v3 bypasses CloudFormation entirely. Instead of compiling a static template, SST v3 communicates directly with cloud APIs via Pulumi. This architectural pivot yields near-instantaneous deployment speeds, parallel resource provisioning, and freedom from CloudFormation's notorious 500-resource limit per stack. However, it also introduces a massive shift in how infrastructure state is managed, making SST Ion one of the most compelling AWS CDK alternatives on the market.
Local Developer Experience: sst dev vs. CDK's Missing Link
When evaluating developer experience (DX), the contrast between SST Ion vs AWS CDK becomes stark. Historically, developing serverless applications on AWS required painful compromises. Developers either had to mock AWS services locally using brittle emulation tools like serverless-offline or LocalStack, or repeatedly deploy changes to the cloud, resulting in a sluggish feedback loop.
SST v3 solves this with its signature feature: sst dev (formerly known as Live Lambda Development).
Start live development mode
npx sst dev
When you run sst dev, the framework deploys an ephemeral "stub" Lambda function to your real AWS environment. When an AWS event (such as an API Gateway request, an SQS message, or an S3 upload) triggers this stub, AWS routes the request payload back to your local machine via a WebSocket connection. Your local code executes, complete with hot-reloading and full debugger/breakpoint support, and pipes the response back to AWS.
This architecture guarantees that your local code interacts with real cloud resources without requiring local emulation or Docker containers. If your Lambda writes to a real DynamoDB table or accesses an RDS database, it does so securely and in real-time.
AWS CDK v2 does not offer an equivalent native live development mode. To test a CDK-defined Lambda function locally, you must rely on manual mocking, execute SAM local invocations, or use cdk watch to continuously deploy code changes. While cdk watch speeds up the deployment of asset-only changes (like Lambda code), it still takes several seconds to package, upload, and update the function, lagging far behind the sub-second hot-reloading loop of SST.
Code Comparison: Defining Infrastructure in TypeScript
Let's compare how both frameworks handle a common serverless pattern: an S3 bucket, a PostgreSQL database (RDS), and a Lambda function that processes API requests. Notice how SST v3 leverages auto-generated type bindings to eliminate manual environment variable management.
The SST v3 Approach (sst.config.ts)
In SST v3, your entire infrastructure is defined in a single, highly readable TypeScript configuration file.
typescript
// sst.config.ts
///
// Provision an RDS Serverless PostgreSQL Database
const database = new sst.aws.Postgres("AppDatabase", {
scaling: {
min: "0 ACU", // Scale to zero when idle to save costs
max: "2 ACU",
},
});
// Provision the API Lambda function linked to resources
const apiHandler = new sst.aws.Function("ApiHandler", {
handler: "src/api/handler.main",
link: [bucket, database], // Automatic type-safe resource binding
});
// Expose via HTTP API Gateway
new sst.aws.ApiGatewayV2("MyApi", {
routes: {
"GET /data": apiHandler,
"POST /upload": apiHandler,
},
});
return {
bucketName: bucket.name,
};
}, });
The SST v3 Lambda Handler (src/api/handler.ts)
Because of SST's link system, you do not need to hardcode S3 bucket names or database connection strings into your environment variables. SST automatically generates a type-safe Resource object:
typescript import { Resource } from "sst"; import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3"; import { Pool } from "pg";
const s3 = new S3Client({}); const db = new Pool({ connectionString: Resource.AppDatabase.secretArn });
export const main = async (event: any) => { // TypeScript autocomplete knows exactly what properties are available const bucketName = Resource.UserAssets.name;
await s3.send(new PutObjectCommand({ Bucket: bucketName, Key: "manifest.json", Body: JSON.stringify({ status: "active" }), }));
const { rows } = await db.query("SELECT * FROM users LIMIT 5");
return { statusCode: 200, body: JSON.stringify({ success: true, users: rows }), }; };
The AWS CDK v2 Approach (lib/my-app-stack.ts)
Now, let's look at the equivalent setup using native AWS CDK constructs. The code is significantly more verbose, requiring explicit IAM role grants and manual environment variable wire-ups.
typescript import * as cdk from "aws-cdk-lib"; import * as s3 from "aws-cdk-lib/aws-s3"; import * as rds from "aws-cdk-lib/aws-rds"; import * as ec2 from "aws-cdk-lib/aws-ec2"; import * as lambda from "aws-cdk-lib/aws-lambda"; import * as apigw from "aws-cdk-lib/aws-apigatewayv2"; import * as integrations from "aws-cdk-lib/aws-apigatewayv2-integrations"; import { NodejsFunction } from "aws-cdk-lib/aws-lambda-nodejs"; import { Construct } from "constructs";
export class MyAppStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props);
// VPC required for RDS
const vpc = new ec2.Vpc(this, "MyVpc", { maxAzs: 2 });
// Provision S3 Bucket
const bucket = new s3.Bucket(this, "UserAssets", {
removalPolicy: cdk.RemovalPolicy.DESTROY,
autoDeleteObjects: true,
});
// Provision RDS Serverless v2 PostgreSQL
const cluster = new rds.DatabaseCluster(this, "AppDatabase", {
engine: rds.DatabaseClusterEngine.auroraPostgres({
version: rds.AuroraPostgresEngineVersion.VER_15_2,
}),
writer: rds.ClusterInstance.serverlessV2("writer"),
vpc,
});
// Provision Lambda Function with automatic esbuild bundling
const apiHandler = new NodejsFunction(this, "ApiHandler", {
entry: "src/api/handler.ts",
runtime: lambda.Runtime.NODEJS_20_X,
environment: {
BUCKET_NAME: bucket.bucketName,
DB_SECRET_ARN: cluster.secret?.secretArn || "",
},
});
// Explicitly grant permissions (No automatic linking)
bucket.grantReadWrite(apiHandler);
if (cluster.secret) {
cluster.secret.grantRead(apiHandler);
}
// Create HTTP API Gateway
const api = new apigw.HttpApi(this, "MyApi");
const integration = new integrations.HttpLambdaIntegration("LambdaIntegration", apiHandler);
api.addRoutes({
path: "/data",
methods: [apigw.HttpMethod.GET],
integration,
});
} }
The AWS CDK Lambda Handler (src/api/handler.ts)
In the CDK paradigm, your application code is decoupled from your infrastructure types. You must parse untyped environment variables and handle potential runtime errors manually:
typescript import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3"; import { Pool } from "pg";
const s3 = new S3Client({}); const bucketName = process.env.BUCKET_NAME; // Untyped string, could be undefined const dbSecretArn = process.env.DB_SECRET_ARN;
if (!bucketName || !dbSecretArn) { throw new Error("Missing required environment variables."); }
export const handler = async (event: any) => { await s3.send(new PutObjectCommand({ Bucket: bucketName, Key: "manifest.json", Body: JSON.stringify({ status: "active" }), }));
// Database initialization logic utilizing secrets manager would go here...
return { statusCode: 200, body: JSON.stringify({ success: true }), }; };
State Management, Drift, and Visibility: CloudFormation vs. API-Driven Speed
One of the most critical operational differences between SST v3 vs AWS CDK lies in state management, deployment visibility, and recovery paths.
AWS CDK: CloudFormation as the Single Source of Truth
AWS CDK has no local or remote state files for you to manage. Instead, CloudFormation is the state. When you execute cdk deploy, CDK synthesizes your TypeScript code into a CloudFormation template and uploads it to AWS. AWS manages the deployment transactionally.
- Transactional Safety: If a deployment fails halfway through (e.g., a database subnet misconfiguration), AWS automatically rolls back the entire stack to its last stable state.
- Drift Detection: CloudFormation natively monitors your resources for manual alterations (drift) made via the AWS Console, allowing you to easily detect when real-world infrastructure deviates from your IaC code.
- Console Visibility: Every resource created by CDK is registered under a CloudFormation stack. Platform engineers can open the AWS Console and inspect the exact event logs, dependency graphs, and resource lists.
SST v3: The API-Driven Pulumi State Engine
SST v3 discards CloudFormation entirely, opting for an API-driven deployment model powered by Pulumi. Instead of deploying templates, SST calls AWS SDK APIs directly to provision resources.
- Deployment Speed: Because SST does not wait on CloudFormation's queue and stack generation layers, deployments are lightning-fast. Updates that would take CDK 5 to 10 minutes are executed by SST Ion in under 30 seconds.
- State File Ownership: Since there is no CloudFormation stack, SST must maintain a state file to keep track of what resources it has deployed. By default, this state is stored in an S3 bucket within your AWS account, but it can be integrated with Pulumi Cloud for team locking and collaboration.
- The Visibility Trade-Off: If an SST deployment fails, there is no native CloudFormation stack in the AWS Console to inspect. You must rely on SST’s CLI output or access the Pulumi state file to debug the failure. If a resource becomes corrupted or stuck, you may need to manually edit the state JSON file—a daunting task that can lead to data loss if executed incorrectly.
Security, IAM, and Secrets: Least-Privilege by Default
Securing serverless applications requires strict adherence to the principle of least privilege. Both frameworks handle IAM policies and secrets management elegantly, but their mechanics differ substantially.
IAM Generation
- SST v3 Link System: SST's
linkproperty automatically generates least-privilege IAM policies. When you link an S3 bucket to a Lambda function, SST analyzes the construct and generates an IAM policy granting only the specific S3 actions required (e.g.,s3:GetObject,s3:PutObject,s3:DeleteObject). You do not have to write manual IAM policy statements. - AWS CDK Grants: CDK utilizes a pattern of explicit grants. Calling
bucket.grantReadWrite(apiHandler)generates the appropriate IAM policy behind the scenes. While highly secure and automated, it requires the developer to remember to write these grant statements for every resource-to-lambda relationship.
Secrets Management
- SST Secrets: SST v3 introduces a native
secret()primitive. Secrets are stored securely in AWS Systems Manager (SSM) Parameter Store or AWS Secrets Manager. During development, you set these secrets via the CLI:
bash npx sst secret set StripeApiKey sk_test_51Nx...
These secrets are then made available to your Lambda functions in a type-safe manner via Resource.StripeApiKey.value, eliminating the need to write custom fetching logic inside your runtime code.
- AWS CDK Secrets: CDK requires you to explicitly provision an
aws-secretsmanager.Secretconstruct and pass its ARN to the Lambda function. The runtime code must then use the AWS SDK to fetch and decrypt the secret at startup, adding cold-start latency and boilerplate code.
Multi-Cloud and Platform Lock-In: Bridging AWS and Cloudflare
For modern web applications, running entirely on AWS isn't always the most cost-effective or high-performance choice. Edge networks like Cloudflare Pages offer superior global latency and zero cold starts for frontend hosting, while AWS remains the undisputed king of heavy backend compute and databases.
This is where the SST Pulumi engine shines. Because SST v3 is built on Pulumi, it supports multi-cloud deployments out of the box.
With SST v3, you can deploy your Next.js, SvelteKit, or Astro frontend directly to Cloudflare Pages, while seamlessly provisioning your database, SQS queues, and Cognito auth on AWS—all from within the same sst.config.ts file.
typescript // Example of a multi-cloud SST v3 configuration const database = new sst.aws.Postgres("MyDatabase");
// Deploy frontend to Cloudflare, linking to AWS RDS new sst.cloudflare.Worker("MyWeb", { handler: "src/worker.ts", link: [database], });
AWS CDK is strictly single-cloud. It is designed by AWS, for AWS. While projects like CDK for Terraform (CDKTF) exist, they are entirely separate tools that do not share the same construct library or developer ecosystem as AWS CDK v2. If your product roadmap requires utilizing edge runtimes outside of AWS (like Cloudflare Workers or Vercel), AWS CDK will lock you into AWS CloudFront and Lambda@Edge.
The SST v3 Migration Guide: Moving from v2 (CDK) to v3 (Ion)
If you are currently running an application on SST v2, migrating to SST v3 is not a simple package upgrade. Because SST v3 transitioned from CDK to Pulumi, the underlying state engine has completely changed. You cannot perform an in-place upgrade of your existing CloudFormation stacks.
To migrate your application safely without downtime, use the following structured SST v3 migration guide:
Step 1: Audit Your Constructs
SST v3 does not support all legacy CDK constructs natively. Identify any raw CDK constructs used in your v2 stacks. In SST v3, you must replace these with Pulumi-based SST components or import the @pulumi/aws library directly.
Step 2: Establish a Dual-Deployment Phase
Do not attempt to destroy your v2 application immediately. Instead, set up SST v3 side-by-side with your v2 stack in your CI/CD pipeline. Point your v3 configurations to copy or share the existing data layers (such as RDS databases and DynamoDB tables) to prevent data loss.
Step 3: Migrate the Data Layer (The "Retain" Strategy)
For stateful resources like S3 Buckets and DynamoDB tables, you must prevent CloudFormation from deleting them during the transition:
1. Update your SST v2 configuration to set the removalPolicy of your databases and buckets to RETAIN.
2. Deploy the v2 stack one final time to apply this policy.
3. Remove these resources from your v2 code and deploy again. The resources will remain active in AWS, but CloudFormation will no longer manage them.
4. Import these existing resources into your SST v3 configuration using Pulumi's import mechanism:
typescript // Importing an existing DynamoDB table into SST v3 const table = new sst.aws.Dynamo("MyTable", { import: "my-existing-table-name" });
Step 4: Cut Over Traffic
Deploy your stateless compute layers (API Gateway, Lambdas, Frontends) via SST v3. Once fully verified, update your Route 53 DNS records to route traffic from your v2 API Gateway/CloudFront endpoints to the new SST v3 endpoints.
Stewardship, Longevity, and Enterprise Support in 2026
Choosing an IaC framework is a multi-year commitment. You must evaluate the longevity and incentives of the maintainers behind the tools.
AWS CDK: The Enterprise Safe Bet
AWS CDK is a first-party, open-source project maintained directly by AWS. Amazon has a massive, long-term incentive to keep CDK updated: the easier it is for developers to deploy to AWS, the more revenue AWS generates.
Every new AWS service or feature launch is accompanied by immediate CDK construct support. For enterprise environments with strict compliance, security audits, and dedicated AWS support contracts, AWS CDK is the gold standard. It is highly stable, highly backward-compatible, and backed by the world's largest cloud provider.
SST v3: The High-Octane Startup Choice
SST is maintained by a highly productive, lean team. While they have built an incredibly passionate community (with over 22k GitHub stars), their corporate focus in 2026 has partially shifted toward adjacent products, such as opencode—an AI-driven coding agent.
While SST v3 remains open-source and actively maintained, relying on a small startup for your entire infrastructure orchestration layer carries inherent platform risk. If the SST team pivots or scales down maintenance, your team will be left managing a highly customized framework built on top of Pulumi.
However, for startups and small-to-medium teams, the massive boost in developer productivity, sub-second local feedback loops, and reduced cloud billing overhead easily outweighs this risk.
Feature Comparison Matrix
| Feature | SST v3 (Ion) | AWS CDK v2 | Serverless Framework v4 |
|---|---|---|---|
| Language | TypeScript | TypeScript, Python, Java, Go | YAML / JSON |
| Underlying Engine | Pulumi (Terraform Providers) | CloudFormation | CloudFormation |
| Deployment Speed | Extremely Fast (seconds) | Slow (minutes) | Moderate (minutes) |
| Local Dev Mode | ✅ sst dev (Real AWS, live debug) |
❌ No native live mode | ✅ sls offline (Emulated local) |
| Type-Safe Bindings | ✅ Auto-generated Resource types |
❌ Manual env variables | ❌ Manual env variables |
| Multi-Cloud Support | ✅ Yes (AWS + Cloudflare) | ❌ No (AWS Only) | ❌ No (AWS Only) |
| State Management | Managed State File (S3 / Pulumi) | CloudFormation (AWS Managed) | CloudFormation (AWS Managed) |
| Licensing | MIT (Free) | Apache 2.0 (Free) | Commercial (Paid for teams) |
| Next.js Support | ✅ Highly Optimized (sst.aws.Nextjs) |
❌ Requires custom constructs | ❌ Requires custom plugins |
| Learning Curve | Low (Developer-centric) | High (Requires AWS expertise) | Low (Config-centric) |
TL;DR: Key Takeaways
- SST v3 (Ion) represents a complete rewrite, abandoning AWS CDK and CloudFormation in favor of a SST Pulumi engine to achieve lightning-fast deployment speeds.
sst devis a game-changing live Lambda debugging environment that routes real cloud events to your local machine, bypassing the need for slow local Docker emulation.- AWS CDK v2 remains the most robust, enterprise-grade tool for single-cloud AWS setups. Its state is managed entirely by CloudFormation, offering native drift detection and transactional rollback safety.
- Type-safe resource bindings in SST v3 auto-generate TypeScript types for your runtime code, eliminating runtime bugs caused by misspelled env variables.
- Multi-cloud architectures are native to SST v3, allowing teams to run frontends on Cloudflare's edge network while keeping databases and compute on AWS.
- Stewardship matters: AWS CDK is backed by Amazon's unlimited resources, whereas SST is maintained by a small, fast-moving startup whose focus is divided among multiple AI-focused developer tools.
Frequently Asked Questions
Is SST v3 cheaper than AWS CDK?
In terms of licensing, both SST v3 and AWS CDK are free and open-source (MIT and Apache 2.0 respectively). However, SST v3 can lower your overall AWS bill during development. Because sst dev executes your Lambda functions locally on your own machine instead of provisioning heavy developer stacks in the cloud, you save on Lambda execution costs and CloudWatch logging fees. Additionally, SST v3's ability to seamlessly scale RDS databases to zero ACUs when idle prevents runaway development costs.
Can I use AWS CDK constructs inside SST v3?
No, you cannot directly import and use AWS CDK constructs inside SST v3. Because SST v3 is built on the Pulumi engine and bypasses CloudFormation, it cannot compile CDK's CloudFormation-based constructs. If you rely on complex, highly customized CDK constructs, you will need to find equivalent Pulumi components or write custom Pulumi resources.
Why did SST drop AWS CDK for Pulumi?
In SST v2, deployments were bottlenecked by CloudFormation. Large serverless stacks would frequently take 5 to 15 minutes to deploy, rollbacks on failure were slow and prone to getting stuck, and teams frequently hit CloudFormation's hard limit of 500 resources per stack. By migrating to Pulumi and Terraform providers in v3, SST achieved parallel, API-driven deployments that take seconds rather than minutes, while gaining native multi-cloud support.
Which is better for Next.js deployments: Vercel, SST, or CDK?
While Vercel offers an unmatched out-of-the-box DX, it adds significant markups on bandwidth, serverless execution limits, and team seats. Deploying Next.js on AWS CDK is notoriously difficult, requiring complex, custom-built constructs to handle SSR and assets. SST v3 features a first-class sst.aws.Nextjs component built on top of Open-Next. This component packages and deploys your Next.js app to AWS (using CloudFront, S3, and Lambda) with 1:1 feature parity with Vercel, but at 1/10th of the hosting cost.
How does sst dev avoid local Docker emulation?
Unlike LocalStack or SAM local, which attempt to emulate AWS APIs inside local Docker containers, sst dev deploys a lightweight "stub" Lambda function directly to your AWS account. This stub acts as a proxy. When AWS triggers the Lambda, the stub forwards the request payload over a WebSocket connection to your local machine, executes your local code, and returns the response. This ensures your code runs against real AWS IAM permissions and cloud resources without any local emulation overhead.
Conclusion
The choice between SST v3 vs AWS CDK comes down to your team's operational priorities and cloud footprint.
If you are a startup or a fast-moving product team building a full-stack TypeScript application (especially with frameworks like Next.js, SvelteKit, or Astro), SST v3 is the clear winner. Its live Lambda development loop, auto-generated type bindings, and edge-hosting integrations with Cloudflare will supercharge your developer productivity and cut your time-to-market in half.
However, if you are an enterprise organization with deep CloudFormation expertise, strict compliance mandates, complex multi-account AWS architectures, or if you prefer to avoid third-party state files, AWS CDK v2 remains the gold standard. It offers unparalleled stability, native AWS support, and a transactional safety net that only first-party tooling can guarantee.
Are you looking to optimize your cloud workflow, or are you exploring new developer productivity tools? Check out our other hands-on comparison guides on CodeBrewTools to keep your engineering stack razor-sharp.


