If you’re building on AWS with TypeScript, this decision looks easy at first.
It isn’t.
Both Pulumi and AWS CDK let you define infrastructure in real programming languages instead of YAML-heavy templates. Both are popular. Both can work really well. And both can become annoying in different ways once your team grows, your stacks multiply, and deployment mistakes start costing actual money.
The reality is this: Pulumi and AWS CDK are not just two ways to write the same thing. They push teams toward different workflows, different mental models, and different kinds of lock-in.
So if you’re wondering which should you choose, the short version is: AWS CDK is usually the safer choice for AWS-only teams. Pulumi is usually better if you want one tool across cloud, app config, and non-AWS resources — or if you want infrastructure code to feel more like normal software.
That’s the quick take.
Now let’s get into what actually matters.
Quick answer
Here’s the direct version:
- Choose AWS CDK if:
- Choose Pulumi if:
If you want the simplest answer to “Pulumi vs AWS CDK for TypeScript,” it’s this:
- Best for AWS-only teams: AWS CDK
- Best for mixed infrastructure and broader platform work: Pulumi
In practice, that’s where most decisions land.
What actually matters
A lot of comparisons get stuck on surface-level feature lists. That’s not very helpful. Both tools can create VPCs, Lambdas, queues, buckets, IAM roles, and all the usual AWS stuff.
What matters is how they behave when your infrastructure gets real.
1. The deployment engine
This is the biggest difference.
AWS CDK synthesizes to CloudFormation. That means CloudFormation is the actual engine applying changes. Pulumi uses its own engine and talks to cloud provider APIs directly through providers.That one architectural difference creates a lot of the trade-offs.
With CDK, you inherit CloudFormation’s strengths and weaknesses:
- mature AWS integration
- good drift handling in some cases
- stack events in AWS
- but also CloudFormation limits
- slower updates in some scenarios
- awkward cross-stack patterns
- occasional “why is this replacement happening?” moments
With Pulumi, you get more flexibility and often a more direct model:
- more providers beyond AWS
- easier composition across services
- often more natural dependency handling
- but you’re relying on Pulumi’s engine and state model instead of AWS-native CloudFormation
If you’ve used both, this is the real fork in the road.
2. How “real” the TypeScript feels
Both claim TypeScript support. That’s true, but not equally true.
Pulumi feels more like writing normal TypeScript.You can still hit Pulumi-specific concepts like Output, async-ish value handling, and resource dependency semantics. But overall, it feels closer to regular code.
That’s not a criticism exactly. It’s just the truth. You’re still thinking in stacks, logical IDs, tokens, synthesis, and CloudFormation-compatible outputs. The TypeScript is nice, but the underlying model is AWS infrastructure templating.
If your team wants infra code to behave like application code, Pulumi usually feels better.
If your team is fine with AWS abstractions and wants a strong AWS-native path, CDK feels coherent.
3. How fast new AWS features show up
This one matters more than people admit.
CDK usually tracks AWS very well, especially through low-level L1 constructs generated from CloudFormation resource specs. Even if a high-level abstraction doesn’t exist yet, you can often use the raw CloudFormation-backed construct.Pulumi also supports AWS quickly, but the path is different and sometimes less predictable depending on the provider version and package generation flow.
Contrarian point: people often say Pulumi is “more modern,” so it must move faster. Not always. For brand-new AWS service support, CDK often has the edge simply because it sits so close to CloudFormation.
If you adopt new AWS services early, this is worth paying attention to.
4. State and operational model
Pulumi has explicit state. CDK, through CloudFormation, has stack state managed by AWS.
That changes your day-to-day operations.
With CDK, your source of truth is mostly:
- your code
- synthesized templates
- CloudFormation stacks in AWS
With Pulumi, your source of truth includes:
- your code
- Pulumi state backend
- Pulumi stack configuration
- provider metadata
This is not inherently bad. In some ways Pulumi’s state model is more powerful. But it is another operational concern.
A lot of teams underestimate that.
5. Team boundaries and platform shape
If your platform team supports:
- AWS
- Kubernetes
- DNS
- observability
- secrets/config
- edge services
- SaaS integrations
Pulumi starts making more sense.
If your world is mostly:
- Lambda
- API Gateway
- DynamoDB
- SQS
- EventBridge
- RDS
- IAM
- VPC
then CDK is often enough, and sometimes better.
The key differences are less about syntax and more about what kind of platform you’re building.
Comparison table
| Area | Pulumi | AWS CDK |
|---|---|---|
| Best for | Multi-tool platform teams, broader infra scope | AWS-focused teams |
| Deployment engine | Pulumi engine + provider APIs | CloudFormation |
| TypeScript experience | More natural, closer to regular code | Good, but CloudFormation-shaped |
| AWS service coverage | Strong | Usually stronger/faster for new AWS features |
| Multi-cloud / non-AWS | Excellent | Weak outside AWS |
| State management | Pulumi state backend required | CloudFormation stack state in AWS |
| Cross-resource composition | Flexible | Can get awkward across stacks |
| Debugging changes | Good previews, but Pulumi-specific model | CloudFormation events are familiar to AWS teams |
| Learning curve | Easy to start, deeper once Output shows up | Easy if you already understand AWS/CloudFormation |
| Ecosystem fit | Great for mixed providers and platform engineering | Great for AWS-native orgs |
| Lock-in | Pulumi platform model | AWS + CloudFormation model |
| Best for TypeScript devs who want normal code | Usually yes | Sometimes, but less so |
Detailed comparison
1. Developer experience in TypeScript
This is where Pulumi wins for a lot of people.
Writing Pulumi in TypeScript generally feels like using a real language, not a DSL pretending to be one. You can organize code in a straightforward way. Reuse patterns feel less forced. Data transformations feel more natural.
That said, Pulumi is not “just TypeScript.” The moment you deal with values only known at deploy time, you run into Output. If you’re new to Pulumi, this can be confusing. You start asking things like:
- Why can’t I just read this string?
- Why do I need
applyhere? - Why does this look async but not exactly async?
So yes, Pulumi feels more natural — until it doesn’t. That’s the contrarian point. People oversell how simple it is. Pulumi is nicer than CDK for TypeScript, but it still has its own programming model.
CDK feels more structured and sometimes more constrained. Constructs, props, stack boundaries, and tokenized values are predictable once you learn them. It’s less elegant, but often easier for AWS teams to reason about because the abstractions map to known AWS concepts.
My opinion:
- Pulumi is more enjoyable to write
- CDK is often easier to explain to AWS-heavy teams
Those are not the same thing.
2. Abstractions and reuse
Both tools support reusable components.
In CDK, you’ll create:
- constructs
- custom constructs
- stacks
- maybe internal libraries of higher-level patterns
This works well, especially if your team wants opinionated building blocks like:
CompanyApiServiceStandardLambdaPrivateFargateService
CDK constructs are a strong model. Honestly, this is one of CDK’s best ideas.
Pulumi has component resources and regular language-level composition. That gives you freedom. You can build abstractions in a way that feels less framework-ish and more like software design.
The trade-off is consistency.
With CDK, teams often converge on a standard way of structuring infra code. With Pulumi, teams can build cleaner abstractions — or a messier one. It depends on discipline.
In practice, CDK is slightly better for teams that want guardrails. Pulumi is better for teams that want fewer constraints.
3. AWS coverage and service maturity
If your question is “which should you choose for deep AWS work,” this section matters a lot.
CDK has a first-party advantage. It is built for AWS, around AWS, and backed by AWS. That means:
- examples are everywhere
- docs are AWS-centric
- new services tend to appear quickly
- support paths are clearer
- your team can usually find someone who has seen the issue before
Pulumi’s AWS support is very good. For mainstream services, it’s more than good enough. I’ve used it for Lambda, ECS, IAM, S3, RDS, EventBridge, and networking without much trouble.
But if you’re doing niche AWS features, very new launches, or weird CloudFormation-adjacent workflows, CDK often feels less risky.
This is one of those boring truths that matters in production. First-party usually wins on edge cases.
4. Previews, plans, and understanding changes
Both tools let you preview changes, but they feel different.
Pulumi previews are usually readable and practical. You get a clear sense of what will be created, updated, replaced, or deleted. For many developers, this feels more approachable than reading generated infrastructure templates.
CDK has cdk diff, which is useful, but you’re still ultimately dealing with CloudFormation behavior. Sometimes the diff looks okay and the deploy gets weird because CloudFormation resolves something differently than expected.
To be fair, Pulumi is not magic here either. Replacement behavior can still surprise you, especially with provider-level semantics.
The real difference is emotional:
- Pulumi often feels like the tool understands your intent
- CDK often feels like you’re negotiating with CloudFormation
That sounds a bit dramatic, but if you’ve spent time with both, you know what I mean.
5. State, drift, and recovery
This is where CDK gets underrated.
Because CDK relies on CloudFormation, operational recovery often fits existing AWS workflows. Stack events, rollback behavior, and the AWS console are familiar territory for many teams.
Pulumi’s state model is powerful, but it introduces another thing to manage carefully. If your state backend, secrets config, stack references, or provider versions drift in messy ways, recovery can be more involved.
Not impossible. Just different.
Contrarian point number two: Pulumi is not automatically simpler operationally just because the code feels cleaner. Sometimes CDK is uglier in code but calmer in operations, especially in conservative AWS environments.
That matters more than people think.
6. Multi-cloud and non-AWS resources
This is Pulumi’s cleanest win.
If you need to manage:
- AWS infrastructure
- Cloudflare DNS
- GitHub repos or team settings
- Datadog monitors
- Kubernetes clusters and manifests
- Vercel or similar services
Pulumi can do that in one model, one language, one workflow.
CDK is not really built for this. Yes, there are ways to stretch it. No, I wouldn’t recommend choosing it for that reason.
This is where the answer to “Pulumi vs AWS CDK for TypeScript” becomes obvious.
If your infrastructure extends beyond AWS in meaningful ways, Pulumi is usually the better fit.
7. Testing and CI/CD
Both support testing, but in different ways.
With CDK, snapshot tests and construct-level assertions are common. This works, though snapshot-heavy testing can become noisy and brittle if overused.
With Pulumi, unit testing component logic often feels more natural because your code is less tied to generated templates. But integration-style validation still matters, because infrastructure behavior is the real thing that counts.
In CI/CD:
- CDK pipelines fit well in AWS-native setups
- Pulumi integrates well in general CI systems and mixed environments
Neither tool is a disaster here. The better choice usually depends on where the rest of your delivery platform lives.
8. Team onboarding
For a junior or mid-level developer who already knows AWS basics, CDK is often easier to place mentally:
- stack
- resources
- outputs
- deploy through CloudFormation
Pulumi can be more approachable at first because it looks like regular TypeScript. But then the hidden complexity shows up:
- outputs
- secrets
- stack config
- provider behavior
- state concerns
So onboarding depends on who you’re onboarding.
- AWS engineers often ramp faster on CDK
- software engineers who dislike infra DSLs often prefer Pulumi
That split is real.
9. Lock-in
Let’s be honest: both lock you in.
CDK locks you into:
- AWS
- CloudFormation
- AWS-shaped infrastructure abstractions
Pulumi locks you into:
- Pulumi state model
- Pulumi resource model
- Pulumi provider ecosystem
The difference is what kind of lock-in you’re okay with.
If you’re already committed to AWS for years, CDK lock-in may not matter much. It might even be a feature.
If you want optionality across providers and tooling, Pulumi gives you more room.
Real example
Let’s make this concrete.
Scenario: a 12-person startup building on AWS
Team:
- 6 backend engineers
- 2 frontend engineers
- 1 DevOps/platform engineer
- 1 data engineer
- 2 founders still touching production
Stack:
- TypeScript services
- Lambda for async jobs
- ECS for APIs
- RDS Postgres
- S3
- CloudFront
- EventBridge
- GitHub Actions
- Cloudflare for DNS
- Datadog for monitoring
They’re asking: which should you choose?
If they pick AWS CDK
This works well if they want to keep the platform narrow and AWS-centric.
Pros:
- AWS docs and examples line up nicely
- the platform engineer can build reusable constructs fast
- the team can rely on CloudFormation-backed deployment behavior
- future AWS hires probably know the model already
Pain points:
- Cloudflare and Datadog become separate tooling concerns
- cross-system automation gets fragmented
- some app teams will feel like infra code is “special” and harder to work with
- stack boundaries can become annoying as the system grows
CDK is a solid choice if this startup expects to stay mostly inside AWS and wants a boring, supportable path.
If they pick Pulumi
This also works well — maybe better — if they want one workflow across the whole platform.
Pros:
- AWS + Cloudflare + Datadog can sit in one codebase
- TypeScript-heavy engineers can contribute more easily
- reusable infra modules can look like normal software components
- platform code can evolve with fewer CloudFormation-shaped constraints
Pain points:
- state management becomes a real operational dependency
- some engineers will misuse
Outputand create confusing code - debugging weird provider behavior may require more Pulumi-specific knowledge
- if they need a brand-new AWS feature immediately, they may hit friction sooner than with CDK
For this startup, I’d probably choose Pulumi if the platform engineer is strong and the team wants one tool across everything.
I’d choose CDK if they want lower conceptual sprawl and expect AWS to remain 90% of the platform story.
Different scenario: enterprise internal platform team
Now imagine:
- 40 engineers
- strict AWS governance
- security review processes
- centralized IAM controls
- heavy use of native AWS tooling
- lots of existing CloudFormation knowledge
Here I’d lean AWS CDK much more strongly.
Not because Pulumi can’t work. It can. But because the surrounding org already thinks in AWS-native terms, and introducing another state and deployment model may create more friction than value.
This is why “best for” depends so much on context.
Common mistakes
1. Choosing Pulumi because “it’s just TypeScript”
It’s not just TypeScript.
It’s TypeScript plus a resource graph, deploy-time values, state, providers, and Pulumi-specific semantics. If your team treats it like a normal backend app, they’ll write weird infrastructure code fast.
2. Choosing CDK because “it’s native, so it must be simpler”
Not necessarily.
CDK inherits CloudFormation complexity. Sometimes that’s fine. Sometimes it’s exactly the thing that slows you down. Native doesn’t always mean easier.
3. Ignoring operational recovery
Teams spend too much time comparing syntax and not enough time asking:
- how do failed deployments recover?
- where is state stored?
- who debugs drift?
- how do we handle partial failures?
That stuff matters more after month three than the elegance of your class structure.
4. Overbuilding abstractions too early
This happens in both tools.
A team starts with a simple Lambda or ECS service. Two weeks later they’ve built a giant internal platform framework no one understands.
Keep abstractions small until patterns are real.
5. Assuming multi-cloud matters when it doesn’t
A lot of teams say they want flexibility, but in reality they are deeply AWS-only and will stay that way.
If that’s you, don’t overvalue Pulumi’s multi-cloud story. It’s great, but only if you’ll actually use it.
Who should choose what
Here’s the clearest guidance I can give.
Choose AWS CDK if you are:
- an AWS-only or mostly AWS team
- already comfortable with CloudFormation concepts
- in a larger org with AWS-native governance
- likely to adopt new AWS features early
- building internal standards around AWS constructs
- optimizing for familiarity and first-party alignment
CDK is best for teams that want to stay close to AWS and don’t mind the CloudFormation-shaped model underneath.
Choose Pulumi if you are:
- managing AWS plus other providers or SaaS infrastructure
- a TypeScript-heavy engineering team that wants infra code to feel more like software
- building a broader platform, not just AWS resources
- frustrated by CloudFormation limits
- okay owning an additional state/deployment model
- willing to learn Pulumi’s value and dependency semantics properly
Pulumi is best for teams that want flexibility, broader scope, and a more natural programming experience.
A simple rule
If your question is mostly “How should we manage AWS?”, choose CDK.
If your question is “How should we manage our platform?”, choose Pulumi.
That rule is not perfect, but it’s surprisingly useful.
Final opinion
If a friend asked me, “Pulumi vs AWS CDK for TypeScript — which should you choose?” I’d answer like this:
- For pure AWS work, I’d default to AWS CDK
- For modern platform engineering across AWS and beyond, I’d default to Pulumi
That’s my actual stance.
CDK is the safer recommendation for many teams because it aligns with how AWS already works. It’s easier to justify, easier to hire for, and usually better for first-party service coverage.
But if I’m being honest about what I enjoy using more in TypeScript, it’s Pulumi.
Pulumi often feels less like infrastructure templating and more like engineering. That matters. It makes teams more willing to maintain the code, not just tolerate it.
Still, I wouldn’t recommend Pulumi blindly. If your org is heavily AWS-native, conservative, and operationally anchored in CloudFormation, CDK may be the smarter choice even if it’s less pleasant.
So the final call is:
- Choose CDK for AWS depth and organizational fit
- Choose Pulumi for flexibility and developer experience
If you’re stuck between them and your environment is standard AWS app infrastructure, pick CDK and move on.
If you already know your world includes non-AWS systems and you want one TypeScript-based infrastructure workflow, pick Pulumi.
FAQ
Is Pulumi better than AWS CDK for TypeScript?
For pure TypeScript developer experience, I think yes. It usually feels more natural. But that doesn’t mean it’s better overall. If you’re deeply AWS-focused, CDK can still be the better choice.
Which is best for AWS-only teams?
Usually AWS CDK.
It’s closer to AWS, often gets new service support faster, and fits better with AWS-native operations. That’s hard to beat if AWS is your whole platform.
Which is best for startups?
Depends on the startup.
If the startup uses AWS plus Cloudflare, GitHub, Datadog, maybe Kubernetes later — Pulumi is often the better fit.
If the startup is just building on core AWS services and wants a simple, reliable path — CDK is a very sensible choice.
What are the key differences between Pulumi and CDK?
The key differences are:
- deployment engine: Pulumi engine vs CloudFormation
- scope: broader platform support vs AWS-first focus
- TypeScript feel: more natural in Pulumi, more AWS-shaped in CDK
- operations: Pulumi state model vs AWS-managed CloudFormation stacks
- service support: CDK often stronger for brand-new AWS features
Can you migrate from CDK to Pulumi or the other way around?
Yes, but don’t expect it to be fun.
You’re not just translating syntax. You’re changing deployment models, state handling, and often how you structure infrastructure code. It’s possible, but it’s a real migration, not a search-and-replace job.