Running Puppeteer in AWS Lambda Environment

I’m trying to set up a serverless function that uses puppeteer to generate PDFs from HTML content. I’ve been working with different Chrome Lambda packages but keep running into issues when the function tries to initialize the browser.

My Current Setup

Here’s my CDK configuration:

const htmlToPdfFunction = new lambda.NodejsFunction(this, 'GeneratePDF', {
  runtime: Runtime.NODEJS_16_X,
  entry: 'functions/pdf-generator/handler.ts',
  timeout: Duration.seconds(15),
  memorySize: 2048,
  layers: [
    LayerVersion.fromLayerVersionArn(this, 'chrome-layer', 'arn:aws:lambda:us-east-1:764866452798:layer:chrome-aws-lambda:25')
  ]
})

Function Implementation

const chrome = require('@sparticuz/chrome-aws-lambda')

export const handler = async (event) => {
  try {
    const browserInstance = await chrome.puppeteer.launch()
    // More logic here
  } catch (err) {
    console.error('Browser launch failed:', err)
    return { statusCode: 500, body: 'Error starting browser' }
  }
}

I keep getting module resolution errors no matter which import method I use. Has anyone successfully deployed puppeteer on Lambda? What’s the correct way to configure the dependencies and imports?

Your issue stems from mixing incompatible packages. The layer you’re using (chrome-aws-lambda:25) is designed for the older chrome-aws-lambda package, not @sparticuz/chrome-aws-lambda. I ran into this exact problem last month. Either switch to puppeteer-core with chrome-aws-lambda package, or update your layer to use Sparticuz’s chromium layer which supports the newer syntax. Also worth noting that your memory allocation at 2048MB is probably overkill - I’ve found 1536MB works well for most PDF generation tasks and saves on costs. The timeout might need bumping to 30 seconds during initial deployment testing, then you can optimize it down based on your actual performance metrics.

The module resolution error you’re encountering might be due to an inconsistency between the packages used. I faced a similar issue, and it was resolved by using @sparticuz/chromium in conjunction with puppeteer-core. Ensure that your layer’s ARN aligns with the package you’re utilizing in your code. Consider updating to the Sparticuz chromium layer or adjusting your imports accordingly. Additionally, remember to set the browser launch options to include headless: true and args: ['--no-sandbox', '--disable-setuid-sandbox'], which are essential for functioning in the Lambda environment. Generally, allocating 1024MB of memory should suffice unless dealing with significantly complex pages.

try installing puppeteer-core instead of regular puppeteer and use executablePath to point to the chrome binary from the layer. also make sure your timeout is higher - 15 secs might not be enough for cold starts