Improving CDK deployment speed for serverless stacks with esbuild

We can easily set up fast deployments with the help of esbuild. Stacks written in CDK can quickly be in the cloud with this great bundler.

1. Previous experience

Throughout my career in development I have met various solutions to deploy stacks to AWS. I have been fortunate to use CloudFormation, SAM, CDK and Serverless Framework.

Most of the time I work with serverless technologies. I use TypeScript and Node.js, but Lambda functions only accept JavaScript code.

Code conversion, bundling, and deployment could take quite a few minutes, which sometimes seems an eternity. I find it frustrating when I make small changes in the stack, and then I must wait long minutes for the updated stack in the cloud.

esbuild is an amazingly fast JavaScript bundler that works well with CDK.

2. Sample stack

To demonstrate that, create a sample stack in a folder called test-project:

npx cdk init --language=typescript

This command will create the folder structure for a CDK version 2 stack called TestProject. I update all packages after they are ready because the package creator sometimes lags behind the latest versions.

Let’s create a Lambda function in the lib folder:

import { Duration, Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { NodejsFunction, LogLevel, NodejsFunctionProps } from 'aws-cdk-lib/aws-lambda-nodejs';
import { Runtime } from 'aws-cdk-lib/aws-lambda';
import { RetentionDays } from 'aws-cdk-lib/aws-logs';

const lambdaFnProps: Partial<NodejsFunctionProps> = {
  bundling: {
    target: 'es2020',
    keepNames: true,
    logLevel: LogLevel.INFO,
    sourceMap: true,
    minify: true,
  },
  runtime: Runtime.NODEJS_16_X,
  timeout: Duration.seconds(6),
  memorySize: 256,
  logRetention: RetentionDays.ONE_DAY,
  environment: {
    NODE_OPTIONS: '--enable-source-maps',
  },
};

export class TestProjectStack extends Stack {
  constructor(scope: Construct, id: string, props: StackProps) {
    super(scope, id, props);

    new NodejsFunction(this, 'test', {
      ...lambdaFnProps,
      functionName: 'TestFn',
    });
  }
}

If we want to deploy the stack, we can run npm run cdk deploy. But at this point we will need Docker running, otherwise the command will return an error.

3. Using esbuild

We have set up some bundling options in the stack module, but CDK is still using a Docker image for bundling.

We can achieve great deployment times if we avoid using Docker and install esbuild locally:

npm install -D esbuild

And this is all about it. The npm run cdk deploy command will now work without Docker, and the deployment will be fast. CDK will use esbuild to automatically transpile TypeScript to JavaScript. We don’t have to use webpack or other bundlers as CDK and esbuild will solve everything for us.

4. Summary

esbuild is a great module bundler, which CDK v2 uses for transpiling TypeScript code at deployment time. We should install the package locally if we want to benefit from esbuild’s fast bundling and CDK’s improved deployment time.

5. Further reading

esbuild documentation - Everything about esbuild