Skip to main content
0.22 is the first release of CDK Terrain (cdktn), the community continuation of CDK for Terraform (cdktf).
The goal of this first release was to rename the project (old packages are deprecated) and to do this with minimal impact to any existing consumers of the project.

Migration Process

CLI

# Install the new CLI
npm install -g cdktn-cli
The cdktn cli should be fully compatible with existing CDK for Terraform projects for at least v0.22.

Project Impact

1. Update package.json dependencies:
{
  "dependencies": {
-   "cdktf": "^0.21.0",
+   "cdktn": "^0.22.0",
-   "@cdktf/provider-aws": "^19.0.0"
+   "@cdktn/provider-aws": "^20.0.0"
  },
  "devDependencies": {
-   "cdktf-cli": "^0.21.0"
+   "cdktn-cli": "^0.22.0"
  }
}
2. Update imports:
- import { App, TerraformStack, TerraformOutput } from "cdktf";
+ import { App, TerraformStack, TerraformOutput } from "cdktn";

- import { AwsProvider } from "@cdktf/provider-aws/lib/provider";
+ import { AwsProvider } from "@cdktn/provider-aws/lib/provider";
3. Update npm scripts:
{
  "scripts": {
-   "get": "cdktf get",
-   "synth": "cdktf synth"
+   "get": "cdktn get",
+   "synth": "cdktn synth"
  }
}
4. Reinstall dependencies:
rm -rf node_modules package-lock.json
npm install

What Stays the Same

The following items are unchanged and backward compatible:
ItemValueNotes
Configuration filecdktf.jsonNo rename needed
Output directorycdktf.out/Still the default
Environment variablesCDKTF_*Still honored
Home directory~/.cdktfStill used
Terraform provider sourceshashicorp/aws, etc.Unchanged
Terraform stateYour .tfstate filesUnaffected

Transitional Period (Dual Dependencies)

If you use prebuilt providers that haven’t been updated to @cdktn/provider-* yet, you may temporarily have both cdktf and cdktn installed:
{
  "dependencies": {
    "cdktn": "^0.22.0",
    "@cdktf/provider-aws": "^19.0.0" // Still uses cdktf peer dep
  }
}
This is partially supported but not recommended long-term. You may run into type errors depending on your usage.
Such as:
Type 'TerraformCount' is not assignable to type 'number | TerraformCount | undefined'.
  Type 'import("node_modules/cdktn/lib/terraform-count").TerraformCount' is not assignable to type 'import("node_modules/cdktf/lib/terraform-count").TerraformCount'.
    Types have separate declarations of a private property 'count'.
This is a result of types not matching (one is cdktf (referenced by cdktf providers) and the other is cdktn).
Depending on your language / package manager you may be able to resolve temporarily until cdktn providers are available.
Using pnpm it would look like:
# In pnpm-workspace.yaml

overrides:
  cdktf: "$cdktn"
It may also be possible to specifically reference the cdktf version of a type temporarily. For example:
- Lifecycle = new TerraformResourceLifecycle()
+ Lifecycle = new Hashicorp.Cdktf.TerraformResourceLifecycle()

Bundle Size Impact

When both packages are installed:
  • Bundle size: Approximately 2x larger (both packages included)
  • Tree-shaking: Bundlers will remove unused exports, reducing actual impact
  • Shared dependencies: constructs is deduplicated between packages
Complete migration promptly to reduce bundle size and complexity.

Options

  1. Wait: Use @cdktf/provider-* until @cdktn/provider-* is released
  2. Generate locally (Recommended): Use cdktn get to generate provider bindings without prebuilt packages
# Generate local provider bindings (recommended for clean migration)
cdktn get
Generating provider bindings for larger providers uses a significant amount of memory (up to 16GB).

Verification

After migration, verify your project works:
# Synthesize
cdktn synth

# Verify output
ls cdktf.out/stacks/*/cdk.tf.json

# Check no cdktf imports remain (TypeScript example)
grep -r "from \"cdktf\"" src/
grep -r "from '@cdktf/" src/

# Run tests (TypeScript example)
npm test

Troubleshooting

Ensure you’ve updated ALL imports. Search for remaining cdktf references:
# TypeScript
grep -rn "cdktf" --include="*.ts" --include="*.tsx"

# Python
grep -rn "cdktf" --include="*.py"
If a prebuilt provider requires a specific cdktf version:
  1. Check if @cdktn/provider-* version is available
  2. If not, use cdktn get to generate local bindings
If you see state drift after migration, verify:
  1. Internal symbols were NOT changed (they should still be cdktf/*)
  2. Logical IDs were NOT changed (still __cdktf_*)
  3. Run cdktn diff to see actual differences

Getting Help