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:
- you’re all-in on AWS - you want first-party alignment with AWS services - your team is comfortable with CloudFormation as the deployment engine - you care more about AWS-native support than multi-cloud flexibility
  • Choose Pulumi if:
- you want to use TypeScript in a more natural way - you need AWS plus other providers like Cloudflare, Kubernetes, Datadog, Vercel, etc. - you want better cross-resource composition beyond CloudFormation boundaries - you want a tool that feels less AWS-shaped

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.

CDK is TypeScript wrapped around CloudFormation concepts.

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

AreaPulumiAWS CDK
Best forMulti-tool platform teams, broader infra scopeAWS-focused teams
Deployment enginePulumi engine + provider APIsCloudFormation
TypeScript experienceMore natural, closer to regular codeGood, but CloudFormation-shaped
AWS service coverageStrongUsually stronger/faster for new AWS features
Multi-cloud / non-AWSExcellentWeak outside AWS
State managementPulumi state backend requiredCloudFormation stack state in AWS
Cross-resource compositionFlexibleCan get awkward across stacks
Debugging changesGood previews, but Pulumi-specific modelCloudFormation events are familiar to AWS teams
Learning curveEasy to start, deeper once Output shows upEasy if you already understand AWS/CloudFormation
Ecosystem fitGreat for mixed providers and platform engineeringGreat for AWS-native orgs
Lock-inPulumi platform modelAWS + CloudFormation model
Best for TypeScript devs who want normal codeUsually yesSometimes, 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 apply here?
  • 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:

  • CompanyApiService
  • StandardLambda
  • PrivateFargateService

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 Output and 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.

Pulumi vs AWS CDK for TypeScript

1) Quick fit by user/profile

2) Simple decision tree