Improving CDK deployment speed for serverless stacks with esbuild
Tags: aws, cdk, serverless, typescript
Published: 2022-06-09 04:06:43

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 <a href="https://aws.amazon.com/cloudformation/" class="link" target="_blank" rel="noopener noreferrer">CloudFormation</a>, <a href="https://aws.amazon.com/serverless/sam/" class="link" target="_blank" rel="noopener noreferrer">SAM</a>, <a href="https://aws.amazon.com/cdk/" class="link" target="_blank" rel="noopener noreferrer">CDK</a> and <a href="https://www.serverless.com/framework/" class="link" target="_blank" rel="noopener noreferrer">Serverless Framework</a>.

Most of the time I work with serverless technologies. I use <a href="https://www.typescriptlang.org/" class="link" target="_blank" rel="noopener noreferrer">TypeScript</a> and <a href="https://nodejs.org/en/" class="link" target="_blank" rel="noopener noreferrer">Node.js</a>, but <a href="https://aws.amazon.com/lambda/" class="link" target="_blank" rel="noopener noreferrer">Lambda</a> 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`:

```bash
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:

```ts
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 <a href="https://www.docker.com/" class="link" target="_blank" rel="noopener noreferrer">Docker</a> 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 <a href="https://github.com/aws/aws-cdk/blob/main/packages/%40aws-cdk/aws-lambda-nodejs/lib/Dockerfile" class="link" target="_blank" rel="noopener noreferrer">Docker image</a> for bundling.

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

```bash
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 <a href="https://webpack.js.org/" class="link" target="_blank" rel="noopener noreferrer">webpack</a> 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

<a href="https://esbuild.github.io/" class="link" target="_blank" rel="noopener noreferrer">esbuild documentation</a> - Everything about `esbuild`