cdktf compile optimization with swc

Laying the grounds works, there are a number of tools in analysis here:

I am interested in using the cdktf, with typescript, to enhance infrastructure as code declarations for ease of use.

Seeing large projects take on the challenge of changing their compiler made me think if it was worth it; what are the pros and cons.


Sample code can be found here:

result chart



Compiler Command Mean [s] Min [s] Max [s] Relative
swc yarn synth 4.9 ± 0.2 4.7 5.2 1.0
tsc yarn synth 28.0 ± 3.8 24.9 32.2 5.6 ± 0.8

TSC incremental vs. SWC

Compiler Command Mean [s] Min [s] Max [s] Relative
swc yarn synth 5.098 ± 0.439 4.661 5.540 1.07 ± 0.12
tsc --incremental yarn synth 4.744 ± 0.341 4.360 5.008 1.00

Read on if you want to know about the implementation details


There is a guide here I followed for getting started with cdktf:

This isn't really the subject of the blog, but it is a nice intro to get you started if you plan on using the cdktf.

Experiencing slow synth

I was doing some development on the train, and I was thinking, wow, this seems slow. When I discovered this was actually the compiler, not the network I was pretty shocked.

Digging under the hood there is actually some fairly good reasons this feels like a slow experience, and there are a number of solutions.

  1. The cdktf was setup to re-compile the code, including all files in the .gen folder, on every synth.
  2. The cdktf was setup with a tsconfig.json that wasn't using incremental builds (tsc keeps a build manifest to help it detect relevant changes and only recompile what is necessary).
  3. The cdktf was setup with a tsconfig.json that would produce type declarations (*.d.ts); which is super useful if you are distributing your code for use in js environments. If you are not, and you are just using typescript, you might not need these.

Solution 1

Just set incremental to true in the tsconfig.json.

I am not going to lie, this is the simplest, and biggest win for compile time, and improves the overall performance straight away.

"compilerOptions": {
"incremental": true

Solution 2

Since the initial build is still slow, another transpiler, swc, could be used to speed up builds:

yarn add --dev @swc/core @swc/cli
// .swcrc
"jsc": {
"parser": {
"syntax": "typescript"
"target": "es2018"
"sourceMaps": true,
"module": {
"type": "commonjs",
"strict": false,
"noInterop": false,
"strictMode": false

Update the compile script to use swc:

"scripts": {
"compile": "swc main.ts --out-file dist/main.js & swc .gen/providers/**/*.ts -d dist/.gen/"


I used hyperfine on my local machine:

$ lshw -short
H/W path Device Class Description
system Latitude 7490 (081C)
/0/4d/0 memory 16GiB SODIMM DDR4 Synchronous Unbuffered (Unregistered) 2133 MHz (0.5 ns)
/0/4d/1 memory 16GiB SODIMM DDR4 Synchronous Unbuffered (Unregistered) 2133 MHz (0.5 ns)
/0/54 processor Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz

TSC --incremental vs. SWC

Testing against incremental, we allow for the build to be present before each run:

hyperfine 'COMMAND=compile yarn synth' \
'COMMAND=build yarn synth' \
--export-csv results/complete.csv


To test without incremental we perform cleaning of the dist directory between runs:

hyperfine 'COMMAND=compile yarn synth' \
'COMMAND=build yarn synth' \
--prepare 'yarn clean' \
--export-csv results/complete.csv


Thanks for reading the methods, hopefully this is useful analysis if you are considering implementing swc of tsc --incremental.