Skip to content

Instantly share code, notes, and snippets.

@renanborgez
Forked from kettanaito/README.md
Created January 5, 2024 20:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save renanborgez/da4635b3220b086c3c6cfb862927b626 to your computer and use it in GitHub Desktop.
Save renanborgez/da4635b3220b086c3c6cfb862927b626 to your computer and use it in GitHub Desktop.
Chromium on Vercel (serveless)

Chromium on Vercel (serverless)

This is an up-to-date guide on running Chromium in Vercel serverless functions in 2022. What you will read below is the result of two days of research, debugging, 100+ failed deployments, and a little bit of stress.

Getting started

Step 1: Install dependencies

Use chrome-aws-lambda that comes with Chromium pre-configured to run in serverless, and puppeteer-core due to the smaller size of Chromium distributive.

Turns out, choosing the right versions of dependencies is crucial. Newer versions of puppeteer-core ship larger Chromium distributive, which will exceed the 50MB function size limit on Vercel.

{
  "chrome-aws-lambda": "10.1.0",
  // Install v10 to have a smaller Chromium distributive.
  "puppeteer-core": "10.1.0"
}

If you feel adventerous and wish to update dependencies, start from updating chrome-aws-lambda. Its peer dependency on puppeteer-core will tell you the maximum supported version to use.

Why not Playwright?

Playwright comes with a larger Chromimum instance that would exceed the maximum allowed serverless function size limit of 50MB on Vercel (transitively, AWS).

Step 2: Write a function

The way you write your function does not matter: it may be a Node.js function, a part of your Next.js /api routes, or a Remix application. What matters on this stage is to launch Puppeteer with correct options.

// api/run.js
import edgeChromium from 'chrome-aws-lambda'

// Importing Puppeteer core as default otherwise
// it won't function correctly with "launch()"
import puppeteer from 'puppeteer-core'

// You may want to change this if you're developing
// on a platform different from macOS.
// See https://github.com/vercel/og-image for a more resilient
// system-agnostic options for Puppeteeer.
const LOCAL_CHROME_EXECUTABLE = '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'

export default async function (req, res) {
  // Edge executable will return an empty string locally.
  const executablePath = await edgeChromium.executablePath || LOCAL_CHROME_EXECUTABLE
  
  const browser = await puppeteer.launch({
    executablePath,
    args: edgeChromium.args,
    headless: false,
  })
  
  const page = await browser.newPage()
  await page.goto('https://github.com')
  
  res.send('hello')
}

Step 3: Configure Vercel deployment

Choose Node.js 14.x

puppeteer-core@10 doesn't work well with newer versions of Node.js. The pinned version should be Node.js 14.

  1. Go to your Vercel project.
  2. Go to "Settings", then "General".
  3. Locate the "Node.js version" section.
  4. Select "Node 14".

Screen Shot 2022-10-22 at 13 11 56

In addition to configuring this on Vercel, make sure that your project's package.json doesn't have the engines.node property that would contradict your choise:

{
  "engines": {
    // If you have a newer version of Node in your package.json
    // Vercel will respect that and disregard what you've set
    // in your project's settings.
    "node": "14.x"
  }
}

Basically, you should not see this warning in your deployment logs:

Warning: Detected "engines": { "node": ">=14" } in your `package.json` that will automatically upgrade when a new major Node.js Version is released. Learn More: http://vercel.link/node-version

If you do, this means your Node.js version is not configured correctly and you should repeat this section.


References


Troubleshooting

Serverless function exceeds the maximum size limit of 50mb

Error: The Serverless Function "XYZ" is XX.YYmb which exceeds the maximum size limit of 50mb. Learn More: https://vercel.link/serverless-function-size

This means you're deploying a Chromium executable that's too large. Solve this by Installing the right dependency versions.

libnss3.so

Error while loading shared libraries: libnss3.so: cannot open shared object file: No such file or directory

This error means you're running an older/newer version of Node.js rather than Node.js 14. Solve this by Using the right Node.js version.

People on the web will suggest all sorts of things to tackle this, like installing libnss3.so manually, but fret not: it's solved by using the right version of Node.js.


If you found this helpful, consider Buying me a cup of coffee.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment