Bundling Prisma with the CDK using aws-lambda-nodejs
Tags: prisma, aws, lambda, typescript
Published: 2021-03-11 13:56:39

## Introduction

In this post, we shall see how we can bundle Prisma using [aws-lambda-nodejs](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-lambda-nodejs-readme.html) with the CDK.

## Prerequisites

This is a walkthrough of the steps required to bundle Prisma with CDK and so cloning the repo below and following along would be ideal.

{% github ryands17/prisma-lambda no-readme %}

## Constructs

In this project, we have a simple [Lambda function](https://github.com/ryands17/prisma-lambda/blob/main/functions/index.ts) that uses Prisma to query data from a `User` table and logs to the console. The only resource we create here is the Lambda function so let's look at that.

I'm skipping the imports in these snippets to make it smaller but if you want to view those you can check those out in the file mentioned in the comments.

```ts
// lib/prisma-lambda-stack.ts

new ln.NodejsFunction(this, 'prisma', {
  runtime: lambda.Runtime.NODEJS_14_X,
  handler: 'handler',
  entry: lambdaFn,
  timeout: cdk.Duration.seconds(10),
  environment: {
    DB_URL: process.env.DB_URL || '',
  },
  bundling: {
    nodeModules: ['@prisma/client', 'prisma'],
    commandHooks: {
      beforeBundling(inputDir: string, outputDir: string): string[] {
        return []
      },
      beforeInstall(inputDir: string, outputDir: string) {
        return [`cp -R ../prisma ${outputDir}/`]
      },
      afterBundling(inputDir: string, outputDir: string): string[] {
        return [
          `cd ${outputDir}`,
          `yarn prisma generate`,
          `rm -rf node_modules/@prisma/engines`,
        ]
      },
    },
  },
})
```

Here, we create a simple Node.js Lambda function and the parameters like `runtime`, `handler`, `entry`, `timeout` and `environment` are the basic Lambda parameters that we pass.

`aws-lambda-nodejs` uses [esbuild](https://esbuild.github.io/) under the hood so your function is bundled using `esbuild`. There are a couple of important parameters that we need to set for the bundling process.

- The first is `nodeModules`. This will instruct `esbuild` to not include `@prisma/client` and `prisma` into our function file and treat them as `node_modules`.

- The other section to be configured is `commandHooks`. The main hooks we need here are `beforeInstall` and `afterBundling`.

  - In `beforeInstall`, we run the command `cp -R ../prisma ${outputDir}/`. This makes sure we have `schema.prisma` present in the bundle. You can also directly copy `schema.prisma` instead of the entire directory if you have the `migrations` folder which is not required in the bundle.

  - The other hook we use is `afterBundling`. This is to generate `PrismaClient` and to remove the `engines` folder to reduce function size.

The rest is a simple Prisma setup with a [schema.prisma](https://github.com/ryands17/prisma-lambda/blob/main/prisma/schema.prisma) and a `User` model.

Now when we run `cdk synth`, the function will be bundled and ready for deployment.

## Conclusion

So this is how we can package Prisma with `aws-lambda-nodejs`.

Here is the repo again for those who haven't checked it out:

{% github ryands17/prisma-lambda no-readme %}