AWS Builder Center

cdkd Is More Than Blazing-Fast CDK Deploys: Trying Out Every Command

cdkd is an open-source CLI that deploys your existing AWS CDK code up to 15x faster by calling the AWS SDK and Cloud Control API directly. But speed isn't all it offers. This post walks through its commands, from running Lambda and API Gateway locally to fixing drift, removing deletion protection, and moving stacks to and from CloudFormation.

2026 Japan AWS Top Engineer, 2024-2026 Japan AWS All Certifications Engineer

AI writes the code in seconds, and we still wait minutes to deploy it

Hi! I'm Hayakawa, and I love AWS CDK!
Coding agents now write pretty good CDK code, so for small setups I hardly write CDK code by hand anymore.
But even if the code takes no time to write, cdk deploy still makes you wait several minutes, just like before.
cdkd (CDK Direct), an open-source tool by AWS Hero Goto-san (go-to-k ), solves this problem.
It is a CLI that speeds up deployment of your existing code: just replace cdk deploy with cdkd deploy, and you get deploys up to 15 times faster!
It was also presented at AWS CDK Conference Japan 2026 , which I attended, and I had been curious about it ever since.
Reading the README, I found that cdkd comes with a lot of commands.
In this post, I'll walk through cdkd's commands along with when to use them!
※ This post is based on the main branch (v0.284.x) as of August 2026. As the documentation states, cdkd is not recommended for production use.

Getting started with cdkd

cdk deploy works in two steps:
  • Synthesize a CloudFormation template from your CDK code
  • Hand the template to CloudFormation and let it deploy
cdkd replaces the second step.
Instead of going through CloudFormation, it calls the AWS SDK and the Cloud Control API directly.
That's why it's fast!
Since there is no CloudFormation stack, cdkd keeps the stack state, which CloudFormation used to hold, in an S3 bucket.
1
2
npm i -g @go-to-k/cdkd
cdkd bootstrap # Replaces cdk bootstrap; run once per account. Creates the S3 bucket (and more) that holds stack state
After that, you just replace cdk with cdkd. You don't touch your CDK code, so you keep developing with CDK the same way as before.
1
2
cdkd deploy # replaces cdk deploy
cdkd destroy # replaces cdk destroy
In his introduction article  (in Japanese), Goto-san himself writes that cdkd "complements the AWS CDK CLI rather than replacing it."
A good approach seems to be deploying quickly with cdkd during development and leaving production to the official CDK CLI.

Everyday commands (synth / deploy / diff / destroy)

The everyday commands are almost the same as in the official CDK CLI, so there's nothing new to learn.
1
2
3
4
5
6
7
cdkd synth
cdkd deploy # picked automatically if there is only one stack
cdkd deploy MyStack
cdkd deploy --all
cdkd deploy --dry-run # show the plan without changing anything
cdkd diff MyStack --fail # exit code 1 if there are differences
cdkd destroy MyStack
If a deployment fails partway through, cdkd rolls back the resources it created or modified, just like the official CDK CLI.
Note, however, that its behavior and guarantees are not necessarily identical to CloudFormation's rollback.
With --no-rollback, cdkd skips the rollback and leaves the intermediate state in place.
If you want to roll back later, there is also cdkd rollback.
I tried it on a small stack with just DynamoDB, Lambda, and API Gateway, and the first deployment finished in 29.22 seconds.
1
2
3
4
5
6
Deploying 16 resource(s) (DAG: 7 levels, max parallel: 10)
[1/16] ✓ ApiF70053CD (AWS::ApiGateway::RestApi) created
[2/16] ✓ HandlerServiceRoleFCDC14AE (AWS::IAM::Role) created
IAM propagation delay for ApiAccountA18C9B29 (attempt 1/3), retrying in 10s...
...
Duration: 29.22s
cdkd expands the resource dependencies into a directed acyclic graph  (DAG) with 7 levels and runs up to 10 operations in parallel.
When IAM propagation hadn't caught up yet, it retried instead of failing.

Choose how long to wait (--no-wait / --full-wait)

cdk deploy is slow because, after asking AWS to create a resource, CloudFormation waits until it can confirm that the resource is ready to use.
cdkd waits only when something else in the same deployment needs that state, or when waiting lets it detect a failure.
For example, a CloudFront distribution takes 3 to 15 minutes to propagate to the edge after creation.
But nothing in the same deployment needs that propagation to finish, so by default cdkd moves on as soon as CreateDistribution is accepted.
The following two options change this behavior.
OptionApplies toBehavior
--no-waitRDS, ElastiCache, NAT Gateway, EC2 instances, ELBv2 load balancers, Lambda MicroVM ImageWaits by default; with this option, moves on as soon as the create API returns
--full-waitECS services, CloudFront distributionsDoesn't wait by default; with this option, waits until ECS tasks are stable and until CloudFront has finished propagating
Note that --no-wait is deploy-only.
According to the README, it isn't available for destroy because a NAT Gateway that is still being deleted holds on to its ENI, and deleting other resources then fails with DependencyViolation.

Run without deploying (cdkd local)

Roughly speaking, cdkd local is like sam local: it runs everything from Lambda, API Gateway, ECS, ALB, and CloudFront to Bedrock AgentCore Runtime locally.
1
2
cdkd local invoke MyStack/Handler
cdkd local start-api MyStack/MyApi --watch
A common source of errors in local runs is environment variables that reference other resources.
For example, if a Lambda function reads from a DynamoDB table, CDK passes the table name in an environment variable such as TABLE_NAME.
But the table name isn't decided until deployment.
The template CDK synthesizes contains only a placeholder (Ref) meaning "fill in the actual name later," so running locally alone can't resolve it.
cdkd solves this by replacing Ref and Fn::ImportValue in environment variables, secrets, and image URIs with the actual values from the deployed stack.
Which flag to use depends on whether you deployed the stack with cdk or with cdkd.
How the stack was deployedFlagWhere values come from
cdk deploy (managed by CloudFormation)--from-cfn-stackCloudFormation stack
cdkd deploy (managed by cdkd)--from-statecdkd state (S3)
1
cdkd local start-api MyStack/MyApi --from-cfn-stack
Without either flag, cdkd only prints a warning and doesn't pass that environment variable.
Here's what happened when I deployed the setup above with cdkd and tried it without a flag.
1
2
3
4
Environment variable TABLE_NAME contains a CloudFormation intrinsic and was dropped.
Override it with --env-vars ..., or pass --from-state / --from-cfn-stack to recover deployed values.

{"message":"hello from cdkd","tableName":null,"stage":"dev"}
Adding --from-state puts the actual table name into tableName.
1
{"message":"hello from cdkd","tableName":"CdkdDemoApi-Items5C12978B","stage":"dev"}
start-api reads from the CDK app which path routes to which Lambda function, and starts a local HTTP server as is.
1
2
3
4
ApiF70053CD (REST API v1) (http://127.0.0.1:39073)
Discovered routes:
ANY / -> Handler886CB40B (REST v1, stage 'prod')
ANY /{proxy+} -> Handler886CB40B (REST v1, stage '
prod')
In other words, you can keep deploying with cdk deploy and install cdkd just for local runs.
With local start-cloudfront, if you only use CloudFront Functions and an S3 origin, you don't even need Docker, and you can check changes to your routing function in seconds.

Find and fix drift (cdkd drift)

CloudFormation drift detection only looks at the properties written in the template.
cdkd is different: it records the state on the AWS side at deployment time and compares it with the current state, so changes made in the console to settings not in the template also show up as differences.
1
2
3
4
cdkd drift MyStack # exit code 1 if there are differences
cdkd drift MyStack --accept --yes # state ← AWS (treat the console changes as correct)
cdkd drift MyStack --revert --yes # AWS ← state (undo the console changes)
cdkd drift MyStack --json # output in a format CI can read
With --dry-run, you can check the planned resolution without changing the state or the AWS resources.

Delete and clean up (destroy / orphan / gc)

destroy deletes both the AWS resources and their records in the state, while orphan deletes only the state records and leaves the AWS resources in place.
1
2
cdkd destroy MyStack
cdkd orphan MyStack/MyBucket # remove just one resource from the state

Remove deletion protection in one go (--remove-protection)

This happens all the time in test environments: if RDS or DynamoDB has deletion protection enabled, destroy stops with an AWS error.
It doesn't delete everything else and leave just the protected resources; it fails right there.
You end up disabling the protection in the console and running destroy again.
1
cdkd destroy MyStack --remove-protection
cdkd disables deletion protection right before deleting each resource, so you don't have to fix your CDK code and redeploy.
Since this is a fairly dangerous option, cdkd thoughtfully changes the confirmation prompt's default from Y/n to y/N.
There is also --skip-final-snapshot.
The CDK L2 construct for RDS defaults to SNAPSHOT, so in a test environment this makes destroy several minutes faster.

Clean up accumulated assets (cdkd gc)

cdkd destroy doesn't empty the S3 bucket and ECR repository for assets that cdkd bootstrap created.
cdkd gc is the command that deletes them.
1
2
cdkd gc --older-than 30d --dry-run # list unreferenced assets older than 30 days without deleting them
cdkd gc --older-than 30d # actually delete them
gc aborts if even one stack is being deployed, so run it when no deployments are in progress.

View state without a CDK app (cdkd state)

All the commands so far assume you have the CDK source code at hand, but the cdkd state commands are the exception: they look only at the state bucket in S3.
They come in handy when you don't have the source, or when you don't want to spend time on synth.
1
2
3
4
5
6
7
cdkd state info # bucket name, region, schema version
cdkd state list # list of stacks and regions
cdkd state list --tree # parent-child tree of nested stacks
cdkd state show MyStack # contents of the state
cdkd state resources MyStack # logical ID, type, physical ID
cdkd state destroy MyStack # delete the stack including its resources, without a CDK app
cdkd state orphan MyStack # delete only the state records

Moving back and forth with CloudFormation (import / export)

Even a stack already built with cdk deploy can be taken out of CloudFormation's management and moved under cdkd's management, without affecting the AWS resources.
You use cdkd import for this.
1
cdkd import MyStack --migrate-from-cloudformation --yes
cdkd reads the mapping between logical IDs and physical IDs from the original CloudFormation stack and imports all resources into the cdkd state.
It then sets Retain on every resource and deletes the original stack.
Now you can use cdkd deploy.
Now suppose you want to move the stack back under CloudFormation's management.
Running cdk deploy won't bring it back.
The original stack is already gone, so CloudFormation would try to create everything from scratch as a new stack.
This is where cdkd export comes in.
1
2
cdkd export MyStack --dry-run # just check what would happen
cdkd export MyStack
It uses a change set with ChangeSetType=IMPORT to bring the existing resources back under CloudFormation's management as is.
On success, the cdkd state is deleted, and you can go back to operating the stack with cdk deploy.

Things to keep in mind when using cdkd

PointDetails
Not recommended for productionThe documentation clearly states that cdkd is meant for development and testing.
IAM permissionsThe IAM user or role that runs cdkd needs permissions to operate the target AWS services directly. If you plan to keep using it, design least-privilege permissions scoped to the target resources, regions, and actions.
Unsupported resourcesAWS resources not supported by an SDK Provider or the Cloud Control API can't be deployed. That said, since everything starts from CDK source code, this may rarely come up in practice...

Summary

In an era when AI lets us write CDK code at high speed, along comes a high-speed deployment tool: cdkd.
Looking into its commands one by one, I found it's much more than just a fast tool.
Here are the commands covered in this post.
What you want to doCommand
Deploy fastercdkd deploy (change how long it waits with --no-wait / --full-wait)
Check the diff firstcdkd diff --fail / cdkd deploy --dry-run
Run locally without deployingcdkd local invoke / start-api (--from-cfn-stack / --from-state)
Find and fix driftcdkd drift (--accept / --revert)
Delete even with deletion protectioncdkd destroy --remove-protection
Delete accumulated assetscdkd gc
View state without the sourcecdkd state list / show / resources
Move back and forth with CloudFormationcdkd import --migrate-from-cloudformation / cdkd export
It's a tool that only an author who knows CDK development inside out could build.
I can't wait to see how its supported resources and operational features grow from here!

References

LinkDescription
cdkd GitHub repository The cdkd repository. The README was extremely helpful
I built cdkd, which deploys up to 15x faster with your existing AWS CDK code Introduction article by the author (in Japanese)
I built AWS CDK from scratch: what I learned about CDK's internals Slides from AWS CDK Conference Japan 2026 (in Japanese)
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article